jtag: cut down on usage of unintended modification of global end state
authorØyvind Harboe <oyvind.harboe@zylin.com>
Tue, 16 Mar 2010 13:13:03 +0000 (14:13 +0100)
committerØyvind Harboe <oyvind.harboe@zylin.com>
Thu, 18 Mar 2010 07:43:19 +0000 (08:43 +0100)
jtag_get/set_end_state() is now deprecated.

There were lots of places in the code where the end state was
unintentionally modified.

The big Q is whether there were any places where the intention
was to modify the end state. 0.5 is a long way off, so we'll
get a fair amount of testing.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
24 files changed:
src/flash/nor/str9xpec.c
src/jtag/core.c
src/jtag/jtag.h
src/pld/virtex2.c
src/target/adi_v5_jtag.c
src/target/arm11_dbgtap.c
src/target/arm720t.c
src/target/arm7_9_common.c
src/target/arm7tdmi.c
src/target/arm920t.c
src/target/arm926ejs.c
src/target/arm966e.c
src/target/arm9tdmi.c
src/target/arm_adi_v5.c.orig [new file with mode: 0644]
src/target/arm_adi_v5.c~ [new file with mode: 0644]
src/target/avrt.c
src/target/dsp563xx.c
src/target/embeddedice.c
src/target/etb.c
src/target/etm.c
src/target/feroceon.c
src/target/mips_ejtag.c
src/target/xscale.c
src/xsvf/xsvf.c

index 35fe806d2e272ce3745b57afd27fc1f9d8c40cd5..732226f598d292e423e5bdc9495b71ba4b27f770 100644 (file)
@@ -69,7 +69,7 @@ static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
        field.in_value = &status;
 
 
-       jtag_add_dr_scan(tap, 1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
        jtag_execute_queue();
 
        LOG_DEBUG("status: 0x%2.2x", status);
@@ -156,7 +156,7 @@ static int str9xpec_read_config(struct flash_bank *bank)
        field.in_value = str9xpec_info->options;
 
 
-       jtag_add_dr_scan(tap, 1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
        jtag_execute_queue();
 
        status = str9xpec_isc_status(tap);
@@ -302,7 +302,7 @@ static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
        field.out_value = buffer;
        field.in_value = NULL;
 
-       jtag_add_dr_scan(tap, 1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
        jtag_add_sleep(40000);
 
        /* read blank check result */
@@ -406,7 +406,7 @@ static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
        field.out_value = buffer;
        field.in_value = NULL;
 
-       jtag_add_dr_scan(tap, 1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
        jtag_execute_queue();
 
        jtag_add_sleep(10);
@@ -466,7 +466,7 @@ static int str9xpec_lock_device(struct flash_bank *bank)
                field.out_value = NULL;
                field.in_value = &status;
 
-               jtag_add_dr_scan(tap, 1, &field, jtag_get_end_state());
+               jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
                jtag_execute_queue();
 
        } while (!(status & ISC_STATUS_BUSY));
@@ -546,7 +546,7 @@ static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
        field.out_value = &sector;
        field.in_value = NULL;
 
-       jtag_add_dr_scan(tap, 1, &field, jtag_get_end_state());
+       jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
 
        return ERROR_OK;
 }
@@ -631,7 +631,7 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
                        field.out_value = (buffer + bytes_written);
                        field.in_value = NULL;
 
-                       jtag_add_dr_scan(tap, 1, &field, jtag_set_end_state(TAP_IDLE));
+                       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
 
                        /* small delay before polling */
                        jtag_add_sleep(50);
@@ -643,7 +643,7 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
                                field.out_value = NULL;
                                field.in_value = scanbuf;
 
-                               jtag_add_dr_scan(tap, 1, &field, jtag_get_end_state());
+                               jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
                                jtag_execute_queue();
 
                                status = buf_get_u32(scanbuf, 0, 8);
@@ -679,7 +679,7 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
                field.out_value = last_dword;
                field.in_value = NULL;
 
-               jtag_add_dr_scan(tap, 1, &field, jtag_set_end_state(TAP_IDLE));
+               jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
 
                /* small delay before polling */
                jtag_add_sleep(50);
@@ -691,7 +691,7 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
                        field.out_value = NULL;
                        field.in_value = scanbuf;
 
-                       jtag_add_dr_scan(tap, 1, &field, jtag_get_end_state());
+                       jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
                        jtag_execute_queue();
 
                        status = buf_get_u32(scanbuf, 0, 8);
@@ -744,7 +744,7 @@ COMMAND_HANDLER(str9xpec_handle_part_id_command)
        field.out_value = NULL;
        field.in_value = buffer;
 
-       jtag_add_dr_scan(tap, 1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
        jtag_execute_queue();
 
        idcode = buf_get_u32(buffer, 0, 32);
@@ -860,7 +860,7 @@ static int str9xpec_write_options(struct flash_bank *bank)
        field.out_value = str9xpec_info->options;
        field.in_value = NULL;
 
-       jtag_add_dr_scan(tap, 1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
 
        /* small delay before polling */
        jtag_add_sleep(50);
@@ -872,7 +872,7 @@ static int str9xpec_write_options(struct flash_bank *bank)
                field.out_value = NULL;
                field.in_value = &status;
 
-               jtag_add_dr_scan(tap, 1, &field, jtag_get_end_state());
+               jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
                jtag_execute_queue();
 
        } while (!(status & ISC_STATUS_BUSY));
index 9792280b20d78e3e1f086f94c237bdc401a7c01d..a09472a76c0133a5c6fc2784da75bb54d3ccf80c 100644 (file)
@@ -743,7 +743,8 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst)
        }
 }
 
-tap_state_t jtag_set_end_state(tap_state_t state)
+/* DEPRECATED! store such global state outside JTAG layer */
+void jtag_set_end_state(tap_state_t state)
 {
        if ((state == TAP_DRSHIFT)||(state == TAP_IRSHIFT))
        {
@@ -752,9 +753,9 @@ tap_state_t jtag_set_end_state(tap_state_t state)
 
        if (state != TAP_INVALID)
                cmd_queue_end_state = state;
-       return cmd_queue_end_state;
 }
 
+/* DEPRECATED! store such global state outside JTAG layer */
 tap_state_t jtag_get_end_state(void)
 {
        return cmd_queue_end_state;
index 0bbea5f561cee6287cdfe5723de803580cddd830..a92c986d1107ef40b37efdbfb020f5f0aace7cc0 100644 (file)
@@ -552,15 +552,18 @@ void jtag_add_reset(int req_tlr_or_trst, int srst);
 
 
 /**
+ * DEPRECATED! store such global state outside JTAG layer
+ *
  * Function jtag_set_end_state
  *
  * Set a global variable to \a state if \a state != TAP_INVALID.
  *
- * Return the value of the global variable.
  */
-tap_state_t jtag_set_end_state(tap_state_t state);
+void jtag_set_end_state(tap_state_t state);
 
 /**
+ * DEPRECATED! store such global state outside JTAG layer
+ * 
  * Function jtag_get_end_state
  *
  * Return the value of the global variable for end state
index 976535b4cd14c2f647350faf666b5fb18b0e66e3..93509dec1cd8ec06eb3a8fd4cac132409d8dab7c 100644 (file)
@@ -40,7 +40,7 @@ static int virtex2_set_instr(struct jtag_tap *tap, uint32_t new_instr)
                buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
                field.in_value = NULL;
 
-               jtag_add_ir_scan(tap, &field, jtag_set_end_state(TAP_IDLE));
+               jtag_add_ir_scan(tap, &field, TAP_IDLE);
 
                free(field.out_value);
        }
@@ -67,7 +67,7 @@ static int virtex2_send_32(struct pld_device *pld_device,
 
        virtex2_set_instr(virtex2_info->tap, 0x5); /* CFG_IN */
 
-       jtag_add_dr_scan(virtex2_info->tap, 1, &scan_field, jtag_set_end_state(TAP_DRPAUSE));
+       jtag_add_dr_scan(virtex2_info->tap, 1, &scan_field, TAP_DRPAUSE);
 
        free(values);
 
@@ -96,7 +96,7 @@ static int virtex2_receive_32(struct pld_device *pld_device,
        {
                scan_field.in_value = (uint8_t *)words;
 
-               jtag_add_dr_scan(virtex2_info->tap, 1, &scan_field, jtag_set_end_state(TAP_DRPAUSE));
+               jtag_add_dr_scan(virtex2_info->tap, 1, &scan_field, TAP_DRPAUSE);
 
                jtag_add_callback(virtexflip32, (jtag_callback_data_t)words);
 
@@ -155,18 +155,18 @@ static int virtex2_load(struct pld_device *pld_device, const char *filename)
        field.num_bits = bit_file.length * 8;
        field.out_value = bit_file.data;
 
-       jtag_add_dr_scan(virtex2_info->tap, 1, &field, jtag_set_end_state(TAP_DRPAUSE));
+       jtag_add_dr_scan(virtex2_info->tap, 1, &field, TAP_DRPAUSE);
        jtag_execute_queue();
 
        jtag_add_tlr();
 
        jtag_set_end_state(TAP_IDLE);
        virtex2_set_instr(virtex2_info->tap, 0xc); /* JSTART */
-       jtag_add_runtest(13, jtag_set_end_state(TAP_IDLE));
+       jtag_add_runtest(13, TAP_IDLE);
        virtex2_set_instr(virtex2_info->tap, 0x3f); /* BYPASS */
        virtex2_set_instr(virtex2_info->tap, 0x3f); /* BYPASS */
        virtex2_set_instr(virtex2_info->tap, 0xc); /* JSTART */
-       jtag_add_runtest(13, jtag_set_end_state(TAP_IDLE));
+       jtag_add_runtest(13, TAP_IDLE);
        virtex2_set_instr(virtex2_info->tap, 0x3f); /* BYPASS */
        jtag_execute_queue();
 
index eac83b7b8228ea3d9ed82efaba49c912708b4b59..091b77ab4c57dbea85d6c0dbb782701a69ead6e5 100644 (file)
@@ -107,7 +107,7 @@ int adi_jtag_dp_scan(struct adiv5_dap *swjdp,
        fields[1].out_value = outvalue;
        fields[1].in_value = invalue;
 
-       jtag_add_dr_scan(jtag_info->tap, 2, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
 
        /* Add specified number of tck clocks after starting memory bus
         * access, giving the hardware time to complete the access.
@@ -119,7 +119,7 @@ int adi_jtag_dp_scan(struct adiv5_dap *swjdp,
                                || ((reg_addr & 0xF0) == AP_REG_BD0))
                        && (swjdp->memaccess_tck != 0))
                jtag_add_runtest(swjdp->memaccess_tck,
-                               jtag_set_end_state(TAP_IDLE));
+                               TAP_IDLE);
 
        return jtag_get_error();
 }
@@ -341,7 +341,7 @@ static int jtag_idcode_q_read(struct adiv5_dap *dap,
        fields[0].out_value = NULL;
        fields[0].in_value = (void *) data;
 
-       jtag_add_dr_scan(jtag_info->tap, 1, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 1, fields, TAP_IDLE);
        retval = jtag_get_error();
        if (retval != ERROR_OK)
                return retval;
index 2b7b4e42d6a56c132113c3910938cc484e991ef7..18bf2555d637c852586ea1613733775404114a7f 100644 (file)
@@ -482,7 +482,7 @@ int arm11_run_instr_data_to_core(struct arm11_common * arm11, uint32_t opcode, u
                {
                        Data        = *data;
 
-                       arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain5_fields), chain5_fields, jtag_set_end_state(TAP_IDLE));
+                       arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain5_fields), chain5_fields, TAP_IDLE);
 
                        CHECK_RETVAL(jtag_execute_queue());
 
index 79eb79be343d5d7aa9ba33c173109cf186f2ba9a..71d4a0172bd1fb5513767b9dd4f7f4be6206c5b0 100644 (file)
@@ -75,15 +75,15 @@ static int arm720t_scan_cp15(struct target *target,
        if (in)
        {
                fields[1].in_value = (uint8_t *)in;
-               jtag_add_dr_scan(jtag_info->tap, 2, fields, jtag_get_end_state());
+               jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
                jtag_add_callback(arm7flip32, (jtag_callback_data_t)in);
        } else
        {
-               jtag_add_dr_scan(jtag_info->tap, 2, fields, jtag_get_end_state());
+               jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
        }
 
        if (clock)
-               jtag_add_runtest(0, jtag_get_end_state());
+               jtag_add_runtest(0, TAP_DRPAUSE);
 
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        if ((retval = jtag_execute_queue()) != ERROR_OK)
index d1e7a93e10c016e9089200acca42c738c1c306ec..c6a08cf1bfb87c1064cf6d2c19d08ff169e00487 100644 (file)
@@ -1750,7 +1750,7 @@ int arm7_9_restart_core(struct target *target)
        }
        arm_jtag_set_instr(jtag_info, 0x4, NULL);
 
-       jtag_add_runtest(1, jtag_set_end_state(TAP_IDLE));
+       jtag_add_runtest(1, TAP_IDLE);
        return jtag_execute_queue();
 }
 
index ab8a3e52dcb54b2ad5144c4b550b8fa84b45336b..2d6d68f61a9340c3026bbba655e46971db3cb96b 100644 (file)
@@ -72,7 +72,7 @@ static int arm7tdmi_examine_debug_reason(struct target *target)
                }
                arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
 
-               jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, jtag_set_end_state(TAP_DRPAUSE));
+               jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE);
                if ((retval = jtag_execute_queue()) != ERROR_OK)
                {
                        return retval;
@@ -83,7 +83,7 @@ static int arm7tdmi_examine_debug_reason(struct target *target)
                fields[1].in_value = NULL;
                fields[1].out_value = databus;
 
-               jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, jtag_set_end_state(TAP_DRPAUSE));
+               jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE);
 
                if (breakpoint & 1)
                        target->debug_reason = DBG_REASON_WATCHPOINT;
@@ -147,11 +147,11 @@ static int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
        fields[1].out_value = NULL;
        fields[1].in_value = (uint8_t *)in;
 
-       jtag_add_dr_scan(jtag_info->tap, 2, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
 
        jtag_add_callback(arm7flip32, (jtag_callback_data_t)in);
 
-       jtag_add_runtest(0, jtag_get_end_state());
+       jtag_add_runtest(0, TAP_DRPAUSE);
 
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        if ((retval = jtag_execute_queue()) != ERROR_OK)
@@ -232,11 +232,11 @@ static int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
        fields[1].out_value = NULL;
        jtag_alloc_in_value32(&fields[1]);
 
-       jtag_add_dr_scan(jtag_info->tap, 2, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
 
        jtag_add_callback4(arm7endianness, (jtag_callback_data_t)in, (jtag_callback_data_t)size, (jtag_callback_data_t)be, (jtag_callback_data_t)fields[1].in_value);
 
-       jtag_add_runtest(0, jtag_get_end_state());
+       jtag_add_runtest(0, TAP_DRPAUSE);
 
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
 {
index a7816fd8c6a61ac817a12d678d2580b6037054ec..68d3997c9a66dc1b6b972a462327331df10b7497 100644 (file)
@@ -111,11 +111,11 @@ static int arm920t_read_cp15_physical(struct target *target,
        fields[3].out_value = &nr_w_buf;
        fields[3].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 4, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
 
        fields[1].in_value = (uint8_t *)value;
 
-       jtag_add_dr_scan(jtag_info->tap, 4, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
 
        jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
 
@@ -162,7 +162,7 @@ static int arm920t_write_cp15_physical(struct target *target,
        fields[3].out_value = &nr_w_buf;
        fields[3].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 4, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
 
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
@@ -214,7 +214,7 @@ static int arm920t_execute_cp15(struct target *target, uint32_t cp15_opcode,
        fields[3].out_value = &nr_w_buf;
        fields[3].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 4, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
 
        arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0);
        arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
index f4c47748cd282e39f5c5e608053a2d27e44f48fd..ea951e55650ce05630ed4dae6980cb1ee5117678 100644 (file)
@@ -86,7 +86,7 @@ static int arm926ejs_cp15_read(struct target *target, uint32_t op1, uint32_t op2
        fields[3].out_value = &nr_w_buf;
        fields[3].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 4, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
 
        long long then = timeval_ms();
 
@@ -95,7 +95,7 @@ static int arm926ejs_cp15_read(struct target *target, uint32_t op1, uint32_t op2
                /* rescan with NOP, to wait for the access to complete */
                access = 0;
                nr_w_buf = 0;
-               jtag_add_dr_scan(jtag_info->tap, 4, fields, jtag_get_end_state());
+               jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
 
                jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
 
@@ -175,7 +175,7 @@ static int arm926ejs_cp15_write(struct target *target, uint32_t op1, uint32_t op
        fields[3].out_value = &nr_w_buf;
        fields[3].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 4, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
 
        long long then = timeval_ms();
 
@@ -184,7 +184,7 @@ static int arm926ejs_cp15_write(struct target *target, uint32_t op1, uint32_t op
                /* rescan with NOP, to wait for the access to complete */
                access = 0;
                nr_w_buf = 0;
-               jtag_add_dr_scan(jtag_info->tap, 4, fields, jtag_get_end_state());
+               jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
                if ((retval = jtag_execute_queue()) != ERROR_OK)
                {
                        return retval;
index 4f4764485afe2ac6d952a471d8651319943dffea..67678c14defa5151768b82316071f69f7f92f745 100644 (file)
@@ -106,11 +106,11 @@ static int arm966e_read_cp15(struct target *target, int reg_addr, uint32_t *valu
        fields[2].out_value = &nr_w_buf;
        fields[2].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
 
        fields[1].in_value = (uint8_t *)value;
 
-       jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
 
        jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
 
@@ -158,7 +158,7 @@ int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value)
        fields[2].out_value = &nr_w_buf;
        fields[2].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
 
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
index f3935a3a2283cd483a3400f183c075fe80e5b2f9..f0911880bb0c486591763dfbf7020e5021b8de69 100644 (file)
@@ -107,7 +107,7 @@ int arm9tdmi_examine_debug_reason(struct target *target)
                }
                arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
 
-               jtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, jtag_set_end_state(TAP_DRPAUSE));
+               jtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, TAP_DRPAUSE);
                if ((retval = jtag_execute_queue()) != ERROR_OK)
                {
                        return retval;
@@ -120,7 +120,7 @@ int arm9tdmi_examine_debug_reason(struct target *target)
                fields[2].in_value = NULL;
                fields[2].out_value = instructionbus;
 
-               jtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, jtag_set_end_state(TAP_DRPAUSE));
+               jtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, TAP_DRPAUSE);
 
                if (debug_reason & 0x4)
                        if (debug_reason & 0x2)
@@ -177,13 +177,13 @@ int arm9tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t instr,
        if (in)
        {
                fields[0].in_value = (uint8_t *)in;
-               jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+               jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);
 
                jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in);
        }
        else
        {
-               jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+               jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);
        }
 
        jtag_add_runtest(0, jtag_get_end_state());
@@ -233,11 +233,11 @@ int arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
        fields[2].out_value = NULL;
        fields[2].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);
 
        jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in);
 
-       jtag_add_runtest(0, jtag_get_end_state());
+       jtag_add_runtest(0, TAP_DRPAUSE);
 
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        {
@@ -300,11 +300,11 @@ int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
        fields[2].out_value = NULL;
        fields[2].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);
 
        jtag_add_callback4(arm9endianness, (jtag_callback_data_t)in, (jtag_callback_data_t)size, (jtag_callback_data_t)be, (jtag_callback_data_t)fields[0].in_value);
 
-       jtag_add_runtest(0, jtag_get_end_state());
+       jtag_add_runtest(0, TAP_DRPAUSE);
 
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        {
diff --git a/src/target/arm_adi_v5.c.orig b/src/target/arm_adi_v5.c.orig
new file mode 100644 (file)
index 0000000..708e858
--- /dev/null
@@ -0,0 +1,1981 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Magnus Lundin                                   *
+ *   lundin@mlu.mine.nu                                                    *
+ *                                                                         *
+ *   Copyright (C) 2008 by Spencer Oliver                                  *
+ *   spen@spen-soft.co.uk                                                  *
+ *                                                                         *
+ *   Copyright (C) 2009 by Oyvind Harboe                                   *
+ *   oyvind.harboe@zylin.com                                               *
+ *                                                                         *
+ *   Copyright (C) 2009-2010 by David Brownell                             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+
+/**
+ * @file
+ * This file implements support for the ARM Debug Interface version 5 (ADIv5)
+ * debugging architecture.  Compared with previous versions, this includes
+ * a low pin-count Serial Wire Debug (SWD) alternative to JTAG for message
+ * transport, and focusses on memory mapped resources as defined by the
+ * CoreSight architecture.
+ *
+ * A key concept in ADIv5 is the Debug Access Port, or DAP.  A DAP has two
+ * basic components:  a Debug Port (DP) transporting messages to and from a
+ * debugger, and an Access Port (AP) accessing resources.  Three types of DP
+ * are defined.  One uses only JTAG for communication, and is called JTAG-DP.
+ * One uses only SWD for communication, and is called SW-DP.  The third can
+ * use either SWD or JTAG, and is called SWJ-DP.  The most common type of AP
+ * is used to access memory mapped resources and is called a MEM-AP.  Also a
+ * JTAG-AP is also defined, bridging to JTAG resources; those are uncommon.
+ *
+ * This programming interface allows DAP pipelined operations through a
+ * transaction queue.  This primarily affects AP operations (such as using
+ * a MEM-AP to access memory or registers).  If the current transaction has
+ * not finished by the time the next one must begin, and the ORUNDETECT bit
+ * is set in the DP_CTRL_STAT register, the SSTICKYORUN status is set and
+ * further AP operations will fail.  There are two basic methods to avoid
+ * such overrun errors.  One involves polling for status instead of using
+ * transaction piplining.  The other involves adding delays to ensure the
+ * AP has enough time to complete one operation before starting the next
+ * one.  (For JTAG these delays are controlled by memaccess_tck.)
+ */
+
+/*
+ * Relevant specifications from ARM include:
+ *
+ * ARM(tm) Debug Interface v5 Architecture Specification    ARM IHI 0031A
+ * CoreSight(tm) v1.0 Architecture Specification            ARM IHI 0029B
+ *
+ * CoreSight(tm) DAP-Lite TRM, ARM DDI 0316D
+ * Cortex-M3(tm) TRM, ARM DDI 0337G
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "arm.h"
+#include "arm_adi_v5.h"
+#include <helper/time_support.h>
+
+
+/* ARM ADI Specification requires at least 10 bits used for TAR autoincrement  */
+
+/*
+       uint32_t tar_block_size(uint32_t address)
+       Return the largest block starting at address that does not cross a tar block size alignment boundary
+*/
+static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address)
+{
+       return (tar_autoincr_block - ((tar_autoincr_block - 1) & address)) >> 2;
+}
+
+/***************************************************************************
+ *                                                                         *
+<<<<<<< HEAD:src/target/arm_adi_v5.c
+=======
+ * DPACC and APACC scanchain access through JTAG-DP                        *
+ *                                                                         *
+***************************************************************************/
+
+/**
+ * Scan DPACC or APACC using target ordered uint8_t buffers.  No endianness
+ * conversions are performed.  See section 4.4.3 of the ADIv5 spec, which
+ * discusses operations which access these registers.
+ *
+ * Note that only one scan is performed.  If RnW is set, a separate scan
+ * will be needed to collect the data which was read; the "invalue" collects
+ * the posted result of a preceding operation, not the current one.
+ *
+ * @param swjdp the DAP
+ * @param instr JTAG_DP_APACC (AP access) or JTAG_DP_DPACC (DP access)
+ * @param reg_addr two significant bits; A[3:2]; for APACC access, the
+ *     SELECT register has more addressing bits.
+ * @param RnW false iff outvalue will be written to the DP or AP
+ * @param outvalue points to a 32-bit (little-endian) integer
+ * @param invalue NULL, or points to a 32-bit (little-endian) integer
+ * @param ack points to where the three bit JTAG_ACK_* code will be stored
+ */
+static int adi_jtag_dp_scan(struct adiv5_dap *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint8_t *outvalue, uint8_t *invalue, uint8_t *ack)
+{
+       struct arm_jtag *jtag_info = swjdp->jtag_info;
+       struct scan_field fields[2];
+       uint8_t out_addr_buf;
+
+       jtag_set_end_state(TAP_IDLE);
+       arm_jtag_set_instr(jtag_info, instr, NULL);
+
+       /* Scan out a read or write operation using some DP or AP register.
+        * For APACC access with any sticky error flag set, this is discarded.
+        */
+       fields[0].num_bits = 3;
+       buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr >> 1) & 0x6) | (RnW & 0x1));
+       fields[0].out_value = &out_addr_buf;
+       fields[0].in_value = ack;
+
+       /* NOTE: if we receive JTAG_ACK_WAIT, the previous operation did not
+        * complete; data we write is discarded, data we read is unpredictable.
+        * When overrun detect is active, STICKYORUN is set.
+        */
+
+       fields[1].num_bits = 32;
+       fields[1].out_value = outvalue;
+       fields[1].in_value = invalue;
+
+       jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
+
+       /* Add specified number of tck clocks after starting memory bus
+        * access, giving the hardware time to complete the access.
+        * They provide more time for the (MEM) AP to complete the read ...
+        * See "Minimum Response Time" for JTAG-DP, in the ADIv5 spec.
+        */
+       if ((instr == JTAG_DP_APACC)
+                       && ((reg_addr == AP_REG_DRW)
+                               || ((reg_addr & 0xF0) == AP_REG_BD0))
+                       && (swjdp->memaccess_tck != 0))
+               jtag_add_runtest(swjdp->memaccess_tck,
+                               TAP_IDLE);
+
+       return jtag_get_error();
+}
+
+/**
+ * Scan DPACC or APACC out and in from host ordered uint32_t buffers.
+ * This is exactly like adi_jtag_dp_scan(), except that endianness
+ * conversions are performed (so the types of invalue and outvalue
+ * must be different).
+ */
+static int adi_jtag_dp_scan_u32(struct adiv5_dap *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint32_t outvalue, uint32_t *invalue, uint8_t *ack)
+{
+       uint8_t out_value_buf[4];
+       int retval;
+
+       buf_set_u32(out_value_buf, 0, 32, outvalue);
+
+       retval = adi_jtag_dp_scan(swjdp, instr, reg_addr, RnW,
+                       out_value_buf, (uint8_t *)invalue, ack);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (invalue)
+               jtag_add_callback(arm_le_to_h_u32,
+                               (jtag_callback_data_t) invalue);
+
+       return retval;
+}
+
+/**
+ * Utility to write AP registers.
+ */
+static inline int adi_jtag_ap_write_check(struct adiv5_dap *dap,
+               uint8_t reg_addr, uint8_t *outvalue)
+{
+       return adi_jtag_dp_scan(dap, JTAG_DP_APACC, reg_addr, DPAP_WRITE,
+                       outvalue, NULL, NULL);
+}
+
+static int adi_jtag_scan_inout_check_u32(struct adiv5_dap *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint32_t outvalue, uint32_t *invalue)
+{
+       int retval;
+
+       /* Issue the read or write */
+       retval = adi_jtag_dp_scan_u32(swjdp, instr, reg_addr,
+                       RnW, outvalue, NULL, NULL);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* For reads,  collect posted value; RDBUFF has no other effect.
+        * Assumes read gets acked with OK/FAULT, and CTRL_STAT says "OK".
+        */
+       if ((RnW == DPAP_READ) && (invalue != NULL))
+               retval = adi_jtag_dp_scan_u32(swjdp, JTAG_DP_DPACC,
+                               DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack);
+       return retval;
+}
+
+static int jtagdp_transaction_endcheck(struct adiv5_dap *swjdp)
+{
+       int retval;
+       uint32_t ctrlstat;
+
+       /* too expensive to call keep_alive() here */
+
+#if 0
+       /* Danger!!!! BROKEN!!!! */
+       adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+       /* Danger!!!! BROKEN!!!! Why will jtag_execute_queue() fail here????
+       R956 introduced the check on return value here and now Michael Schwingen reports
+       that this code no longer works....
+
+       https://lists.berlios.de/pipermail/openocd-development/2008-September/003107.html
+       */
+       if ((retval = jtag_execute_queue()) != ERROR_OK)
+       {
+               LOG_ERROR("BUG: Why does this fail the first time????");
+       }
+       /* Why??? second time it works??? */
+#endif
+
+       /* Post CTRL/STAT read; discard any previous posted read value
+        * but collect its ACK status.
+        */
+       adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+       if ((retval = jtag_execute_queue()) != ERROR_OK)
+               return retval;
+
+       swjdp->ack = swjdp->ack & 0x7;
+
+       /* common code path avoids calling timeval_ms() */
+       if (swjdp->ack != JTAG_ACK_OK_FAULT)
+       {
+               long long then = timeval_ms();
+
+               while (swjdp->ack != JTAG_ACK_OK_FAULT)
+               {
+                       if (swjdp->ack == JTAG_ACK_WAIT)
+                       {
+                               if ((timeval_ms()-then) > 1000)
+                               {
+                                       /* NOTE:  this would be a good spot
+                                        * to use JTAG_DP_ABORT.
+                                        */
+                                       LOG_WARNING("Timeout (1000ms) waiting "
+                                               "for ACK=OK/FAULT "
+                                               "in JTAG-DP transaction");
+                                       return ERROR_JTAG_DEVICE_ERROR;
+                               }
+                       }
+                       else
+                       {
+                               LOG_WARNING("Invalid ACK %#x "
+                                               "in JTAG-DP transaction",
+                                               swjdp->ack);
+                               return ERROR_JTAG_DEVICE_ERROR;
+                       }
+
+                       adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+                       if ((retval = dap_run(swjdp)) != ERROR_OK)
+                               return retval;
+                       swjdp->ack = swjdp->ack & 0x7;
+               }
+       }
+
+       /* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */
+
+       /* Check for STICKYERR and STICKYORUN */
+       if (ctrlstat & (SSTICKYORUN | SSTICKYERR))
+       {
+               LOG_DEBUG("jtag-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
+               /* Check power to debug regions */
+               if ((ctrlstat & 0xf0000000) != 0xf0000000)
+                        ahbap_debugport_init(swjdp);
+               else
+               {
+                       uint32_t mem_ap_csw, mem_ap_tar;
+
+                       /* Maybe print information about last intended
+                        * MEM-AP access; but not if autoincrementing.
+                        * *Real* CSW and TAR values are always shown.
+                        */
+                       if (swjdp->ap_tar_value != (uint32_t) -1)
+                               LOG_DEBUG("MEM-AP Cached values: "
+                                       "ap_bank 0x%" PRIx32
+                                       ", ap_csw 0x%" PRIx32
+                                       ", ap_tar 0x%" PRIx32,
+                                       swjdp->ap_bank_value,
+                                       swjdp->ap_csw_value,
+                                       swjdp->ap_tar_value);
+
+                       if (ctrlstat & SSTICKYORUN)
+                               LOG_ERROR("JTAG-DP OVERRUN - check clock, "
+                                       "memaccess, or reduce jtag speed");
+
+                       if (ctrlstat & SSTICKYERR)
+                               LOG_ERROR("JTAG-DP STICKY ERROR");
+
+                       /* Clear Sticky Error Bits */
+                       adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                                       DP_CTRL_STAT, DPAP_WRITE,
+                                       swjdp->dp_ctrl_stat | SSTICKYORUN
+                                               | SSTICKYERR, NULL);
+                       adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+                       if ((retval = dap_run(swjdp)) != ERROR_OK)
+                               return retval;
+
+                       LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
+
+                       retval = dap_queue_ap_read(swjdp,
+                                       AP_REG_CSW, &mem_ap_csw);
+                       if (retval != ERROR_OK)
+                               return retval;
+
+                       retval = dap_queue_ap_read(swjdp,
+                                       AP_REG_TAR, &mem_ap_tar);
+                       if (retval != ERROR_OK)
+                               return retval;
+
+                       if ((retval = dap_run(swjdp)) != ERROR_OK)
+                               return retval;
+                       LOG_ERROR("MEM_AP_CSW 0x%" PRIx32 ", MEM_AP_TAR 0x%"
+                                       PRIx32, mem_ap_csw, mem_ap_tar);
+
+               }
+               if ((retval = dap_run(swjdp)) != ERROR_OK)
+                       return retval;
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+
+       return ERROR_OK;
+}
+
+/***************************************************************************
+ *                                                                         *
+>>>>>>> jtag: cut down on usage of unintended modification of global end state:src/target/arm_adi_v5.c
+ * DP and MEM-AP  register access  through APACC and DPACC                 *
+ *                                                                         *
+***************************************************************************/
+
+/**
+ * Select one of the APs connected to the specified DAP.  The
+ * selection is implicitly used with future AP transactions.
+ * This is a NOP if the specified AP is already selected.
+ *
+ * @param swjdp The DAP
+ * @param apsel Number of the AP to (implicitly) use with further
+ *     transactions.  This normally identifies a MEM-AP.
+ */
+void dap_ap_select(struct adiv5_dap *swjdp,uint8_t apsel)
+{
+       uint32_t select = (apsel << 24) & 0xFF000000;
+
+       if (select != swjdp->apsel)
+       {
+               swjdp->apsel = select;
+               /* Switching AP invalidates cached values.
+                * Values MUST BE UPDATED BEFORE AP ACCESS.
+                */
+               swjdp->ap_bank_value = -1;
+               swjdp->ap_csw_value = -1;
+               swjdp->ap_tar_value = -1;
+       }
+}
+
+/**
+ * Queue transactions setting up transfer parameters for the
+ * currently selected MEM-AP.
+ *
+ * Subsequent transfers using registers like AP_REG_DRW or AP_REG_BD2
+ * initiate data reads or writes using memory or peripheral addresses.
+ * If the CSW is configured for it, the TAR may be automatically
+ * incremented after each transfer.
+ *
+ * @todo Rename to reflect it being specifically a MEM-AP function.
+ *
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param csw MEM-AP Control/Status Word (CSW) register to assign.  If this
+ *     matches the cached value, the register is not changed.
+ * @param tar MEM-AP Transfer Address Register (TAR) to assign.  If this
+ *     matches the cached address, the register is not changed.
+ *
+ * @return ERROR_OK if the transaction was properly queued, else a fault code.
+ */
+int dap_setup_accessport(struct adiv5_dap *swjdp, uint32_t csw, uint32_t tar)
+{
+       int retval;
+
+       csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT;
+       if (csw != swjdp->ap_csw_value)
+       {
+               /* LOG_DEBUG("DAP: Set CSW %x",csw); */
+               retval = dap_queue_ap_write(swjdp, AP_REG_CSW, csw);
+               if (retval != ERROR_OK)
+                       return retval;
+               swjdp->ap_csw_value = csw;
+       }
+       if (tar != swjdp->ap_tar_value)
+       {
+               /* LOG_DEBUG("DAP: Set TAR %x",tar); */
+               retval = dap_queue_ap_write(swjdp, AP_REG_TAR, tar);
+               if (retval != ERROR_OK)
+                       return retval;
+               swjdp->ap_tar_value = tar;
+       }
+       /* Disable TAR cache when autoincrementing */
+       if (csw & CSW_ADDRINC_MASK)
+               swjdp->ap_tar_value = -1;
+       return ERROR_OK;
+}
+
+/**
+ * Asynchronous (queued) read of a word from memory or a system register.
+ *
+ * @param swjdp The DAP connected to the MEM-AP performing the read.
+ * @param address Address of the 32-bit word to read; it must be
+ *     readable by the currently selected MEM-AP.
+ * @param value points to where the word will be stored when the
+ *     transaction queue is flushed (assuming no errors).
+ *
+ * @return ERROR_OK for success.  Otherwise a fault code.
+ */
+int mem_ap_read_u32(struct adiv5_dap *swjdp, uint32_t address,
+               uint32_t *value)
+{
+       int retval;
+
+       /* Use banked addressing (REG_BDx) to avoid some link traffic
+        * (updating TAR) when reading several consecutive addresses.
+        */
+       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF,
+                       address & 0xFFFFFFF0);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return dap_queue_ap_read(swjdp, AP_REG_BD0 | (address & 0xC), value);
+}
+
+/**
+ * Synchronous read of a word from memory or a system register.
+ * As a side effect, this flushes any queued transactions.
+ *
+ * @param swjdp The DAP connected to the MEM-AP performing the read.
+ * @param address Address of the 32-bit word to read; it must be
+ *     readable by the currently selected MEM-AP.
+ * @param value points to where the result will be stored.
+ *
+ * @return ERROR_OK for success; *value holds the result.
+ * Otherwise a fault code.
+ */
+int mem_ap_read_atomic_u32(struct adiv5_dap *swjdp, uint32_t address,
+               uint32_t *value)
+{
+       int retval;
+
+       retval = mem_ap_read_u32(swjdp, address, value);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return dap_run(swjdp);
+}
+
+/**
+ * Asynchronous (queued) write of a word to memory or a system register.
+ *
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param address Address to be written; it must be writable by
+ *     the currently selected MEM-AP.
+ * @param value Word that will be written to the address when transaction
+ *     queue is flushed (assuming no errors).
+ *
+ * @return ERROR_OK for success.  Otherwise a fault code.
+ */
+int mem_ap_write_u32(struct adiv5_dap *swjdp, uint32_t address,
+               uint32_t value)
+{
+       int retval;
+
+       /* Use banked addressing (REG_BDx) to avoid some link traffic
+        * (updating TAR) when writing several consecutive addresses.
+        */
+       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF,
+                       address & 0xFFFFFFF0);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return dap_queue_ap_write(swjdp, AP_REG_BD0 | (address & 0xC),
+                       value);
+}
+
+/**
+ * Synchronous write of a word to memory or a system register.
+ * As a side effect, this flushes any queued transactions.
+ *
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param address Address to be written; it must be writable by
+ *     the currently selected MEM-AP.
+ * @param value Word that will be written.
+ *
+ * @return ERROR_OK for success; the data was written.  Otherwise a fault code.
+ */
+int mem_ap_write_atomic_u32(struct adiv5_dap *swjdp, uint32_t address,
+               uint32_t value)
+{
+       int retval = mem_ap_write_u32(swjdp, address, value);
+
+       if (retval != ERROR_OK)
+               return retval;
+
+       return dap_run(swjdp);
+}
+
+/*****************************************************************************
+*                                                                            *
+* mem_ap_write_buf(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) *
+*                                                                            *
+* Write a buffer in target order (little endian)                             *
+*                                                                            *
+*****************************************************************************/
+int mem_ap_write_buf_u32(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address)
+{
+       int wcount, blocksize, writecount, errorcount = 0, retval = ERROR_OK;
+       uint32_t adr = address;
+       uint8_t* pBuffer = buffer;
+
+       count >>= 2;
+       wcount = count;
+
+       /* if we have an unaligned access - reorder data */
+       if (adr & 0x3u)
+       {
+               for (writecount = 0; writecount < count; writecount++)
+               {
+                       int i;
+                       uint32_t outvalue;
+                       memcpy(&outvalue, pBuffer, sizeof(uint32_t));
+
+                       for (i = 0; i < 4; i++)
+                       {
+                               *((uint8_t*)pBuffer + (adr & 0x3)) = outvalue;
+                               outvalue >>= 8;
+                               adr++;
+                       }
+                       pBuffer += sizeof(uint32_t);
+               }
+       }
+
+       while (wcount > 0)
+       {
+               /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               /* handle unaligned data at 4k boundary */
+               if (blocksize == 0)
+                       blocksize = 1;
+
+               dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, address);
+
+               for (writecount = 0; writecount < blocksize; writecount++)
+               {
+                       retval = dap_queue_ap_write(swjdp, AP_REG_DRW,
+                               *(uint32_t *) (buffer + 4 * writecount));
+                       if (retval != ERROR_OK)
+                               break;
+               }
+
+               if (dap_run(swjdp) == ERROR_OK)
+               {
+                       wcount = wcount - blocksize;
+                       address = address + 4 * blocksize;
+                       buffer = buffer + 4 * blocksize;
+               }
+               else
+               {
+                       errorcount++;
+               }
+
+               if (errorcount > 1)
+               {
+                       LOG_WARNING("Block write error address 0x%" PRIx32 ", wcount 0x%x", address, wcount);
+                       /* REVISIT return the *actual* fault code */
+                       return ERROR_JTAG_DEVICE_ERROR;
+               }
+       }
+
+       return retval;
+}
+
+static int mem_ap_write_buf_packed_u16(struct adiv5_dap *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
+{
+       int retval = ERROR_OK;
+       int wcount, blocksize, writecount, i;
+
+       wcount = count >> 1;
+
+       while (wcount > 0)
+       {
+               int nbytes;
+
+               /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               /* handle unaligned data at 4k boundary */
+               if (blocksize == 0)
+                       blocksize = 1;
+
+               dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_PACKED, address);
+               writecount = blocksize;
+
+               do
+               {
+                       nbytes = MIN((writecount << 1), 4);
+
+                       if (nbytes < 4)
+                       {
+                               if (mem_ap_write_buf_u16(swjdp, buffer,
+                                               nbytes, address) != ERROR_OK)
+                               {
+                                       LOG_WARNING("Block write error address "
+                                               "0x%" PRIx32 ", count 0x%x",
+                                               address, count);
+                                       return ERROR_JTAG_DEVICE_ERROR;
+                               }
+
+                               address += nbytes >> 1;
+                       }
+                       else
+                       {
+                               uint32_t outvalue;
+                               memcpy(&outvalue, buffer, sizeof(uint32_t));
+
+                               for (i = 0; i < nbytes; i++)
+                               {
+                                       *((uint8_t*)buffer + (address & 0x3)) = outvalue;
+                                       outvalue >>= 8;
+                                       address++;
+                               }
+
+                               memcpy(&outvalue, buffer, sizeof(uint32_t));
+                               retval = dap_queue_ap_write(swjdp,
+                                               AP_REG_DRW, outvalue);
+                               if (retval != ERROR_OK)
+                                       break;
+
+                               if (dap_run(swjdp) != ERROR_OK)
+                               {
+                                       LOG_WARNING("Block write error address "
+                                               "0x%" PRIx32 ", count 0x%x",
+                                               address, count);
+                                       /* REVISIT return *actual* fault code */
+                                       return ERROR_JTAG_DEVICE_ERROR;
+                               }
+                       }
+
+                       buffer += nbytes >> 1;
+                       writecount -= nbytes >> 1;
+
+               } while (writecount);
+               wcount -= blocksize;
+       }
+
+       return retval;
+}
+
+int mem_ap_write_buf_u16(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address)
+{
+       int retval = ERROR_OK;
+
+       if (count >= 4)
+               return mem_ap_write_buf_packed_u16(swjdp, buffer, count, address);
+
+       while (count > 0)
+       {
+               dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
+               uint16_t svalue;
+               memcpy(&svalue, buffer, sizeof(uint16_t));
+               uint32_t outvalue = (uint32_t)svalue << 8 * (address & 0x3);
+               retval = dap_queue_ap_write(swjdp, AP_REG_DRW, outvalue);
+               if (retval != ERROR_OK)
+                       break;
+
+               retval = dap_run(swjdp);
+               if (retval != ERROR_OK)
+                       break;
+
+               count -= 2;
+               address += 2;
+               buffer += 2;
+       }
+
+       return retval;
+}
+
+static int mem_ap_write_buf_packed_u8(struct adiv5_dap *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
+{
+       int retval = ERROR_OK;
+       int wcount, blocksize, writecount, i;
+
+       wcount = count;
+
+       while (wcount > 0)
+       {
+               int nbytes;
+
+               /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_PACKED, address);
+               writecount = blocksize;
+
+               do
+               {
+                       nbytes = MIN(writecount, 4);
+
+                       if (nbytes < 4)
+                       {
+                               if (mem_ap_write_buf_u8(swjdp, buffer, nbytes, address) != ERROR_OK)
+                               {
+                                       LOG_WARNING("Block write error address "
+                                               "0x%" PRIx32 ", count 0x%x",
+                                               address, count);
+                                       return ERROR_JTAG_DEVICE_ERROR;
+                               }
+
+                               address += nbytes;
+                       }
+                       else
+                       {
+                               uint32_t outvalue;
+                               memcpy(&outvalue, buffer, sizeof(uint32_t));
+
+                               for (i = 0; i < nbytes; i++)
+                               {
+                                       *((uint8_t*)buffer + (address & 0x3)) = outvalue;
+                                       outvalue >>= 8;
+                                       address++;
+                               }
+
+                               memcpy(&outvalue, buffer, sizeof(uint32_t));
+                               retval = dap_queue_ap_write(swjdp,
+                                               AP_REG_DRW, outvalue);
+                               if (retval != ERROR_OK)
+                                       break;
+
+                               if (dap_run(swjdp) != ERROR_OK)
+                               {
+                                       LOG_WARNING("Block write error address "
+                                               "0x%" PRIx32 ", count 0x%x",
+                                               address, count);
+                                       /* REVISIT return *actual* fault code */
+                                       return ERROR_JTAG_DEVICE_ERROR;
+                               }
+                       }
+
+                       buffer += nbytes;
+                       writecount -= nbytes;
+
+               } while (writecount);
+               wcount -= blocksize;
+       }
+
+       return retval;
+}
+
+int mem_ap_write_buf_u8(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address)
+{
+       int retval = ERROR_OK;
+
+       if (count >= 4)
+               return mem_ap_write_buf_packed_u8(swjdp, buffer, count, address);
+
+       while (count > 0)
+       {
+               dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
+               uint32_t outvalue = (uint32_t)*buffer << 8 * (address & 0x3);
+               retval = dap_queue_ap_write(swjdp, AP_REG_DRW, outvalue);
+               if (retval != ERROR_OK)
+                       break;
+
+               retval = dap_run(swjdp);
+               if (retval != ERROR_OK)
+                       break;
+
+               count--;
+               address++;
+               buffer++;
+       }
+
+       return retval;
+}
+
+/* FIXME don't import ... this is a temporary workaround for the
+ * mem_ap_read_buf_u32() mess, until it's no longer JTAG-specific.
+ */
+extern int adi_jtag_dp_scan(struct adiv5_dap *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint8_t *outvalue, uint8_t *invalue, uint8_t *ack);
+
+/**
+ * Synchronously read a block of 32-bit words into a buffer
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param buffer where the words will be stored (in host byte order).
+ * @param count How many words to read.
+ * @param address Memory address from which to read words; all the
+ *     words must be readable by the currently selected MEM-AP.
+ */
+int mem_ap_read_buf_u32(struct adiv5_dap *swjdp, uint8_t *buffer,
+               int count, uint32_t address)
+{
+       int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK;
+       uint32_t adr = address;
+       uint8_t* pBuffer = buffer;
+
+       count >>= 2;
+       wcount = count;
+
+       while (wcount > 0)
+       {
+               /* Adjust to read blocks within boundaries aligned to the
+                * TAR autoincrement size (at least 2^10).  Autoincrement
+                * mode avoids an extra per-word roundtrip to update TAR.
+                */
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block,
+                               address);
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               /* handle unaligned data at 4k boundary */
+               if (blocksize == 0)
+                       blocksize = 1;
+
+               dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE,
+                               address);
+
+               /* FIXME remove these three calls to adi_jtag_dp_scan(),
+                * so this routine becomes transport-neutral.  Be careful
+                * not to cause performance problems with JTAG; would it
+                * suffice to loop over dap_queue_ap_read(), or would that
+                * be slower when JTAG is the chosen transport?
+                */
+
+               /* Scan out first read */
+               adi_jtag_dp_scan(swjdp, JTAG_DP_APACC, AP_REG_DRW,
+                               DPAP_READ, 0, NULL, NULL);
+               for (readcount = 0; readcount < blocksize - 1; readcount++)
+               {
+                       /* Scan out next read; scan in posted value for the
+                        * previous one.  Assumes read is acked "OK/FAULT",
+                        * and CTRL_STAT says that meant "OK".
+                        */
+                       adi_jtag_dp_scan(swjdp, JTAG_DP_APACC, AP_REG_DRW,
+                                       DPAP_READ, 0, buffer + 4 * readcount,
+                                       &swjdp->ack);
+               }
+
+               /* Scan in last posted value; RDBUFF has no other effect,
+                * assuming ack is OK/FAULT and CTRL_STAT says "OK".
+                */
+               adi_jtag_dp_scan(swjdp, JTAG_DP_DPACC, DP_RDBUFF,
+                               DPAP_READ, 0, buffer + 4 * readcount,
+                               &swjdp->ack);
+               if (dap_run(swjdp) == ERROR_OK)
+               {
+                       wcount = wcount - blocksize;
+                       address += 4 * blocksize;
+                       buffer += 4 * blocksize;
+               }
+               else
+               {
+                       errorcount++;
+               }
+
+               if (errorcount > 1)
+               {
+                       LOG_WARNING("Block read error address 0x%" PRIx32
+                               ", count 0x%x", address, count);
+                       /* REVISIT return the *actual* fault code */
+                       return ERROR_JTAG_DEVICE_ERROR;
+               }
+       }
+
+       /* if we have an unaligned access - reorder data */
+       if (adr & 0x3u)
+       {
+               for (readcount = 0; readcount < count; readcount++)
+               {
+                       int i;
+                       uint32_t data;
+                       memcpy(&data, pBuffer, sizeof(uint32_t));
+
+                       for (i = 0; i < 4; i++)
+                       {
+                               *((uint8_t*)pBuffer) =
+                                               (data >> 8 * (adr & 0x3));
+                               pBuffer++;
+                               adr++;
+                       }
+               }
+       }
+
+       return retval;
+}
+
+static int mem_ap_read_buf_packed_u16(struct adiv5_dap *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
+{
+       uint32_t invalue;
+       int retval = ERROR_OK;
+       int wcount, blocksize, readcount, i;
+
+       wcount = count >> 1;
+
+       while (wcount > 0)
+       {
+               int nbytes;
+
+               /* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_PACKED, address);
+
+               /* handle unaligned data at 4k boundary */
+               if (blocksize == 0)
+                       blocksize = 1;
+               readcount = blocksize;
+
+               do
+               {
+                       retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue);
+                       if (dap_run(swjdp) != ERROR_OK)
+                       {
+                               LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
+                               /* REVISIT return the *actual* fault code */
+                               return ERROR_JTAG_DEVICE_ERROR;
+                       }
+
+                       nbytes = MIN((readcount << 1), 4);
+
+                       for (i = 0; i < nbytes; i++)
+                       {
+                               *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
+                               buffer++;
+                               address++;
+                       }
+
+                       readcount -= (nbytes >> 1);
+               } while (readcount);
+               wcount -= blocksize;
+       }
+
+       return retval;
+}
+
+/**
+ * Synchronously read a block of 16-bit halfwords into a buffer
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param buffer where the halfwords will be stored (in host byte order).
+ * @param count How many halfwords to read.
+ * @param address Memory address from which to read words; all the
+ *     words must be readable by the currently selected MEM-AP.
+ */
+int mem_ap_read_buf_u16(struct adiv5_dap *swjdp, uint8_t *buffer,
+               int count, uint32_t address)
+{
+       uint32_t invalue, i;
+       int retval = ERROR_OK;
+
+       if (count >= 4)
+               return mem_ap_read_buf_packed_u16(swjdp, buffer, count, address);
+
+       while (count > 0)
+       {
+               dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
+               retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue);
+               if (retval != ERROR_OK)
+                       break;
+
+               retval = dap_run(swjdp);
+               if (retval != ERROR_OK)
+                       break;
+
+               if (address & 0x1)
+               {
+                       for (i = 0; i < 2; i++)
+                       {
+                               *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
+                               buffer++;
+                               address++;
+                       }
+               }
+               else
+               {
+                       uint16_t svalue = (invalue >> 8 * (address & 0x3));
+                       memcpy(buffer, &svalue, sizeof(uint16_t));
+                       address += 2;
+                       buffer += 2;
+               }
+               count -= 2;
+       }
+
+       return retval;
+}
+
+/* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
+ * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
+ *
+ * The solution is to arrange for a large out/in scan in this loop and
+ * and convert data afterwards.
+ */
+static int mem_ap_read_buf_packed_u8(struct adiv5_dap *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
+{
+       uint32_t invalue;
+       int retval = ERROR_OK;
+       int wcount, blocksize, readcount, i;
+
+       wcount = count;
+
+       while (wcount > 0)
+       {
+               int nbytes;
+
+               /* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_PACKED, address);
+               readcount = blocksize;
+
+               do
+               {
+                       retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue);
+                       if (dap_run(swjdp) != ERROR_OK)
+                       {
+                               LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
+                               /* REVISIT return the *actual* fault code */
+                               return ERROR_JTAG_DEVICE_ERROR;
+                       }
+
+                       nbytes = MIN(readcount, 4);
+
+                       for (i = 0; i < nbytes; i++)
+                       {
+                               *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
+                               buffer++;
+                               address++;
+                       }
+
+                       readcount -= nbytes;
+               } while (readcount);
+               wcount -= blocksize;
+       }
+
+       return retval;
+}
+
+/**
+ * Synchronously read a block of bytes into a buffer
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param buffer where the bytes will be stored.
+ * @param count How many bytes to read.
+ * @param address Memory address from which to read data; all the
+ *     data must be readable by the currently selected MEM-AP.
+ */
+int mem_ap_read_buf_u8(struct adiv5_dap *swjdp, uint8_t *buffer,
+               int count, uint32_t address)
+{
+       uint32_t invalue;
+       int retval = ERROR_OK;
+
+       if (count >= 4)
+               return mem_ap_read_buf_packed_u8(swjdp, buffer, count, address);
+
+       while (count > 0)
+       {
+               dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
+               retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue);
+               retval = dap_run(swjdp);
+               if (retval != ERROR_OK)
+                       break;
+
+               *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
+               count--;
+               address++;
+               buffer++;
+       }
+
+       return retval;
+}
+
+/*--------------------------------------------------------------------------*/
+
+<<<<<<< HEAD:src/target/arm_adi_v5.c
+=======
+static int jtag_idcode_q_read(struct adiv5_dap *dap,
+               uint8_t *ack, uint32_t *data)
+{
+       struct arm_jtag *jtag_info = dap->jtag_info;
+       int retval;
+       struct scan_field fields[1];
+
+       jtag_set_end_state(TAP_IDLE);
+
+       /* This is a standard JTAG operation -- no DAP tweakage */
+       retval = arm_jtag_set_instr(jtag_info, JTAG_DP_IDCODE, NULL);
+       if (retval != ERROR_OK)
+               return retval;
+
+       fields[0].num_bits = 32;
+       fields[0].out_value = NULL;
+       fields[0].in_value = (void *) data;
+
+       jtag_add_dr_scan(jtag_info->tap, 1, fields, TAP_IDLE);
+       retval = jtag_get_error();
+       if (retval != ERROR_OK)
+               return retval;
+
+       jtag_add_callback(arm_le_to_h_u32,
+                       (jtag_callback_data_t) data);
+
+       return retval;
+}
+
+static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
+               uint32_t *data)
+{
+       return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+                       reg, DPAP_READ, 0, data);
+}
+
+static int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg,
+               uint32_t data)
+{
+       return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+                       reg, DPAP_WRITE, data, NULL);
+}
+
+/** Select the AP register bank matching bits 7:4 of reg. */
+static int jtag_ap_q_bankselect(struct adiv5_dap *dap, unsigned reg)
+{
+       uint32_t select = reg & 0x000000F0;
+
+       if (select == dap->ap_bank_value)
+               return ERROR_OK;
+       dap->ap_bank_value = select;
+
+       select |= dap->apsel;
+
+       return jtag_dp_q_write(dap, DP_SELECT, select);
+}
+
+static int jtag_ap_q_read(struct adiv5_dap *dap, unsigned reg,
+               uint32_t *data)
+{
+       int retval = jtag_ap_q_bankselect(dap, reg);
+
+       if (retval != ERROR_OK)
+               return retval;
+
+       return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_APACC, reg,
+                       DPAP_READ, 0, data);
+}
+
+static int jtag_ap_q_write(struct adiv5_dap *dap, unsigned reg,
+               uint32_t data)
+{
+       uint8_t out_value_buf[4];
+
+       int retval = jtag_ap_q_bankselect(dap, reg);
+       if (retval != ERROR_OK)
+               return retval;
+>>>>>>> jtag: cut down on usage of unintended modification of global end state:src/target/arm_adi_v5.c
+
+/* FIXME don't import ... just initialize as
+ * part of DAP transport setup
+*/
+extern const struct dap_ops jtag_dp_ops;
+
+/*--------------------------------------------------------------------------*/
+
+/**
+ * Initialize a DAP.  This sets up the power domains, prepares the DP
+ * for further use, and arranges to use AP #0 for all AP operations
+ * until dap_ap-select() changes that policy.
+ *
+ * @param swjdp The DAP being initialized.
+ *
+ * @todo Rename this.  We also need an initialization scheme which account
+ * for SWD transports not just JTAG; that will need to address differences
+ * in layering.  (JTAG is useful without any debug target; but not SWD.)
+ * And this may not even use an AHB-AP ... e.g. DAP-Lite uses an APB-AP.
+ */
+int ahbap_debugport_init(struct adiv5_dap *swjdp)
+{
+       uint32_t idreg, romaddr, dummy;
+       uint32_t ctrlstat;
+       int cnt = 0;
+       int retval;
+
+       LOG_DEBUG(" ");
+
+       /* JTAG-DP or SWJ-DP, in JTAG mode */
+       swjdp->ops = &jtag_dp_ops;
+
+       /* Default MEM-AP setup.
+        *
+        * REVISIT AP #0 may be an inappropriate default for this.
+        * Should we probe, or take a hint from the caller?
+        * Presumably we can ignore the possibility of multiple APs.
+        */
+       swjdp->apsel = !0;
+       dap_ap_select(swjdp, 0);
+
+       /* DP initialization */
+
+       retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = dap_queue_dp_write(swjdp, DP_CTRL_STAT, SSTICKYERR);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy);
+       if (retval != ERROR_OK)
+               return retval;
+
+       swjdp->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
+       retval = dap_queue_dp_write(swjdp, DP_CTRL_STAT, swjdp->dp_ctrl_stat);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &ctrlstat);
+       if (retval != ERROR_OK)
+               return retval;
+       if ((retval = dap_run(swjdp)) != ERROR_OK)
+               return retval;
+
+       /* Check that we have debug power domains activated */
+       while (!(ctrlstat & CDBGPWRUPACK) && (cnt++ < 10))
+       {
+               LOG_DEBUG("DAP: wait CDBGPWRUPACK");
+               retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &ctrlstat);
+               if (retval != ERROR_OK)
+                       return retval;
+               if ((retval = dap_run(swjdp)) != ERROR_OK)
+                       return retval;
+               alive_sleep(10);
+       }
+
+       while (!(ctrlstat & CSYSPWRUPACK) && (cnt++ < 10))
+       {
+               LOG_DEBUG("DAP: wait CSYSPWRUPACK");
+               retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &ctrlstat);
+               if (retval != ERROR_OK)
+                       return retval;
+               if ((retval = dap_run(swjdp)) != ERROR_OK)
+                       return retval;
+               alive_sleep(10);
+       }
+
+       retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy);
+       if (retval != ERROR_OK)
+               return retval;
+       /* With debug power on we can activate OVERRUN checking */
+       swjdp->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT;
+       retval = dap_queue_dp_write(swjdp, DP_CTRL_STAT, swjdp->dp_ctrl_stat);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /*
+        * REVISIT this isn't actually *initializing* anything in an AP,
+        * and doesn't care if it's a MEM-AP at all (much less AHB-AP).
+        * Should it?  If the ROM address is valid, is this the right
+        * place to scan the table and do any topology detection?
+        */
+       retval = dap_queue_ap_read(swjdp, AP_REG_IDR, &idreg);
+       retval = dap_queue_ap_read(swjdp, AP_REG_BASE, &romaddr);
+
+       LOG_DEBUG("MEM-AP #%d ID Register 0x%" PRIx32
+               ", Debug ROM Address 0x%" PRIx32,
+               swjdp->apsel, idreg, romaddr);
+
+       return ERROR_OK;
+}
+
+/* CID interpretation -- see ARM IHI 0029B section 3
+ * and ARM IHI 0031A table 13-3.
+ */
+static const char *class_description[16] ={
+       "Reserved", "ROM table", "Reserved", "Reserved",
+       "Reserved", "Reserved", "Reserved", "Reserved",
+       "Reserved", "CoreSight component", "Reserved", "Peripheral Test Block",
+       "Reserved", "OptimoDE DESS",
+               "Generic IP component", "PrimeCell or System component"
+};
+
+static bool
+is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0)
+{
+       return cid3 == 0xb1 && cid2 == 0x05
+                       && ((cid1 & 0x0f) == 0) && cid0 == 0x0d;
+}
+
+static int dap_info_command(struct command_context *cmd_ctx,
+               struct adiv5_dap *swjdp, int apsel)
+{
+       int retval;
+       uint32_t dbgbase, apid;
+       int romtable_present = 0;
+       uint8_t mem_ap;
+       uint32_t apselold;
+
+       /* AP address is in bits 31:24 of DP_SELECT */
+       if (apsel >= 256)
+               return ERROR_INVALID_ARGUMENTS;
+
+       apselold = swjdp->apsel;
+       dap_ap_select(swjdp, apsel);
+       retval = dap_queue_ap_read(swjdp, AP_REG_BASE, &dbgbase);
+       retval = dap_queue_ap_read(swjdp, AP_REG_IDR, &apid);
+       retval = dap_run(swjdp);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec  */
+       mem_ap = ((apid&0x10000) && ((apid&0x0F) != 0));
+       command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid);
+       if (apid)
+       {
+               switch (apid&0x0F)
+               {
+                       case 0:
+                               command_print(cmd_ctx, "\tType is JTAG-AP");
+                               break;
+                       case 1:
+                               command_print(cmd_ctx, "\tType is MEM-AP AHB");
+                               break;
+                       case 2:
+                               command_print(cmd_ctx, "\tType is MEM-AP APB");
+                               break;
+                       default:
+                               command_print(cmd_ctx, "\tUnknown AP type");
+                               break;
+               }
+
+               /* NOTE: a MEM-AP may have a single CoreSight component that's
+                * not a ROM table ... or have no such components at all.
+                */
+               if (mem_ap)
+                       command_print(cmd_ctx, "AP BASE 0x%8.8" PRIx32,
+                                       dbgbase);
+       }
+       else
+       {
+               command_print(cmd_ctx, "No AP found at this apsel 0x%x", apsel);
+       }
+
+       romtable_present = ((mem_ap) && (dbgbase != 0xFFFFFFFF));
+       if (romtable_present)
+       {
+               uint32_t cid0,cid1,cid2,cid3,memtype,romentry;
+               uint16_t entry_offset;
+
+               /* bit 16 of apid indicates a memory access port */
+               if (dbgbase & 0x02)
+                       command_print(cmd_ctx, "\tValid ROM table present");
+               else
+                       command_print(cmd_ctx, "\tROM table in legacy format");
+
+               /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec  */
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFF0, &cid0);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFF4, &cid1);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFF8, &cid2);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFFC, &cid3);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFCC, &memtype);
+               retval = dap_run(swjdp);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
+                       command_print(cmd_ctx, "\tCID3 0x%2.2" PRIx32
+                                       ", CID2 0x%2.2" PRIx32
+                                       ", CID1 0x%2.2" PRIx32
+                                       ", CID0 0x%2.2" PRIx32,
+                                       cid3, cid2, cid1, cid0);
+               if (memtype & 0x01)
+                       command_print(cmd_ctx, "\tMEMTYPE system memory present on bus");
+               else
+                       command_print(cmd_ctx, "\tMEMTYPE System memory not present. "
+                                       "Dedicated debug bus.");
+
+               /* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */
+               entry_offset = 0;
+               do
+               {
+                       mem_ap_read_atomic_u32(swjdp, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
+                       command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%" PRIx32 "",entry_offset,romentry);
+                       if (romentry&0x01)
+                       {
+                               uint32_t c_cid0, c_cid1, c_cid2, c_cid3;
+                               uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4;
+                               uint32_t component_start, component_base;
+                               unsigned part_num;
+                               char *type, *full;
+
+                               component_base = (uint32_t)((dbgbase & 0xFFFFF000)
+                                               + (int)(romentry & 0xFFFFF000));
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFE0, &c_pid0);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFE4, &c_pid1);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFE8, &c_pid2);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFEC, &c_pid3);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFD0, &c_pid4);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFF0, &c_cid0);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFF4, &c_cid1);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFF8, &c_cid2);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFFC, &c_cid3);
+                               component_start = component_base - 0x1000*(c_pid4 >> 4);
+
+                               command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32
+                                               ", start address 0x%" PRIx32,
+                                               component_base, component_start);
+                               command_print(cmd_ctx, "\t\tComponent class is 0x%x, %s",
+                                               (int) (c_cid1 >> 4) & 0xf,
+                                               /* See ARM IHI 0029B Table 3-3 */
+                                               class_description[(c_cid1 >> 4) & 0xf]);
+
+                               /* CoreSight component? */
+                               if (((c_cid1 >> 4) & 0x0f) == 9) {
+                                       uint32_t devtype;
+                                       unsigned minor;
+                                       char *major = "Reserved", *subtype = "Reserved";
+
+                                       mem_ap_read_atomic_u32(swjdp,
+                                                       (component_base & 0xfffff000) | 0xfcc,
+                                                       &devtype);
+                                       minor = (devtype >> 4) & 0x0f;
+                                       switch (devtype & 0x0f) {
+                                       case 0:
+                                               major = "Miscellaneous";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 4:
+                                                       subtype = "Validation component";
+                                                       break;
+                                               }
+                                               break;
+                                       case 1:
+                                               major = "Trace Sink";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Port";
+                                                       break;
+                                               case 2:
+                                                       subtype = "Buffer";
+                                                       break;
+                                               }
+                                               break;
+                                       case 2:
+                                               major = "Trace Link";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Funnel, router";
+                                                       break;
+                                               case 2:
+                                                       subtype = "Filter";
+                                                       break;
+                                               case 3:
+                                                       subtype = "FIFO, buffer";
+                                                       break;
+                                               }
+                                               break;
+                                       case 3:
+                                               major = "Trace Source";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Processor";
+                                                       break;
+                                               case 2:
+                                                       subtype = "DSP";
+                                                       break;
+                                               case 3:
+                                                       subtype = "Engine/Coprocessor";
+                                                       break;
+                                               case 4:
+                                                       subtype = "Bus";
+                                                       break;
+                                               }
+                                               break;
+                                       case 4:
+                                               major = "Debug Control";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Trigger Matrix";
+                                                       break;
+                                               case 2:
+                                                       subtype = "Debug Auth";
+                                                       break;
+                                               }
+                                               break;
+                                       case 5:
+                                               major = "Debug Logic";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Processor";
+                                                       break;
+                                               case 2:
+                                                       subtype = "DSP";
+                                                       break;
+                                               case 3:
+                                                       subtype = "Engine/Coprocessor";
+                                                       break;
+                                               }
+                                               break;
+                                       }
+                                       command_print(cmd_ctx, "\t\tType is 0x%2.2x, %s, %s",
+                                                       (unsigned) (devtype & 0xff),
+                                                       major, subtype);
+                                       /* REVISIT also show 0xfc8 DevId */
+                               }
+
+                               if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
+                                       command_print(cmd_ctx, "\t\tCID3 0x%2.2" PRIx32
+                                                       ", CID2 0x%2.2" PRIx32
+                                                       ", CID1 0x%2.2" PRIx32
+                                                       ", CID0 0x%2.2" PRIx32,
+                                                       c_cid3, c_cid2, c_cid1, c_cid0);
+                               command_print(cmd_ctx, "\t\tPeripheral ID[4..0] = hex "
+                                               "%2.2x %2.2x %2.2x %2.2x %2.2x",
+                                               (int) c_pid4,
+                                               (int) c_pid3, (int) c_pid2,
+                                               (int) c_pid1, (int) c_pid0);
+
+                               /* Part number interpretations are from Cortex
+                                * core specs, the CoreSight components TRM
+                                * (ARM DDI 0314H), and ETM specs; also from
+                                * chip observation (e.g. TI SDTI).
+                                */
+                               part_num = c_pid0 & 0xff;
+                               part_num |= (c_pid1 & 0x0f) << 8;
+                               switch (part_num) {
+                               case 0x000:
+                                       type = "Cortex-M3 NVIC";
+                                       full = "(Interrupt Controller)";
+                                       break;
+                               case 0x001:
+                                       type = "Cortex-M3 ITM";
+                                       full = "(Instrumentation Trace Module)";
+                                       break;
+                               case 0x002:
+                                       type = "Cortex-M3 DWT";
+                                       full = "(Data Watchpoint and Trace)";
+                                       break;
+                               case 0x003:
+                                       type = "Cortex-M3 FBP";
+                                       full = "(Flash Patch and Breakpoint)";
+                                       break;
+                               case 0x00d:
+                                       type = "CoreSight ETM11";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               // case 0x113: what?
+                               case 0x120:             /* from OMAP3 memmap */
+                                       type = "TI SDTI";
+                                       full = "(System Debug Trace Interface)";
+                                       break;
+                               case 0x343:             /* from OMAP3 memmap */
+                                       type = "TI DAPCTL";
+                                       full = "";
+                                       break;
+                               case 0x906:
+                                       type = "Coresight CTI";
+                                       full = "(Cross Trigger)";
+                                       break;
+                               case 0x907:
+                                       type = "Coresight ETB";
+                                       full = "(Trace Buffer)";
+                                       break;
+                               case 0x908:
+                                       type = "Coresight CSTF";
+                                       full = "(Trace Funnel)";
+                                       break;
+                               case 0x910:
+                                       type = "CoreSight ETM9";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               case 0x912:
+                                       type = "Coresight TPIU";
+                                       full = "(Trace Port Interface Unit)";
+                                       break;
+                               case 0x921:
+                                       type = "Cortex-A8 ETM";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               case 0x922:
+                                       type = "Cortex-A8 CTI";
+                                       full = "(Cross Trigger)";
+                                       break;
+                               case 0x923:
+                                       type = "Cortex-M3 TPIU";
+                                       full = "(Trace Port Interface Unit)";
+                                       break;
+                               case 0x924:
+                                       type = "Cortex-M3 ETM";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               case 0xc08:
+                                       type = "Cortex-A8 Debug";
+                                       full = "(Debug Unit)";
+                                       break;
+                               default:
+                                       type = "-*- unrecognized -*-";
+                                       full = "";
+                                       break;
+                               }
+                               command_print(cmd_ctx, "\t\tPart is %s %s",
+                                               type, full);
+                       }
+                       else
+                       {
+                               if (romentry)
+                                       command_print(cmd_ctx, "\t\tComponent not present");
+                               else
+                                       command_print(cmd_ctx, "\t\tEnd of ROM table");
+                       }
+                       entry_offset += 4;
+               } while (romentry > 0);
+       }
+       else
+       {
+               command_print(cmd_ctx, "\tNo ROM table present");
+       }
+       dap_ap_select(swjdp, apselold);
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(handle_dap_info_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+       uint32_t apsel;
+
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = dap->apsel;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       return dap_info_command(CMD_CTX, dap, apsel);
+}
+
+COMMAND_HANDLER(dap_baseaddr_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+
+       uint32_t apsel, apselsave, baseaddr;
+       int retval;
+
+       apselsave = dap->apsel;
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = dap->apsel;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               /* AP address is in bits 31:24 of DP_SELECT */
+               if (apsel >= 256)
+                       return ERROR_INVALID_ARGUMENTS;
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       if (apselsave != apsel)
+               dap_ap_select(dap, apsel);
+
+       /* NOTE:  assumes we're talking to a MEM-AP, which
+        * has a base address.  There are other kinds of AP,
+        * though they're not common for now.  This should
+        * use the ID register to verify it's a MEM-AP.
+        */
+       retval = dap_queue_ap_read(dap, AP_REG_BASE, &baseaddr);
+       retval = dap_run(dap);
+       if (retval != ERROR_OK)
+               return retval;
+
+       command_print(CMD_CTX, "0x%8.8" PRIx32, baseaddr);
+
+       if (apselsave != apsel)
+               dap_ap_select(dap, apselsave);
+
+       return retval;
+}
+
+COMMAND_HANDLER(dap_memaccess_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+
+       uint32_t memaccess_tck;
+
+       switch (CMD_ARGC) {
+       case 0:
+               memaccess_tck = dap->memaccess_tck;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck);
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+       dap->memaccess_tck = memaccess_tck;
+
+       command_print(CMD_CTX, "memory bus access delay set to %" PRIi32 " tck",
+                       dap->memaccess_tck);
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(dap_apsel_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+
+       uint32_t apsel, apid;
+       int retval;
+
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = 0;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               /* AP address is in bits 31:24 of DP_SELECT */
+               if (apsel >= 256)
+                       return ERROR_INVALID_ARGUMENTS;
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       dap_ap_select(dap, apsel);
+       retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid);
+       retval = dap_run(dap);
+       if (retval != ERROR_OK)
+               return retval;
+
+       command_print(CMD_CTX, "ap %" PRIi32 " selected, identification register 0x%8.8" PRIx32,
+                       apsel, apid);
+
+       return retval;
+}
+
+COMMAND_HANDLER(dap_apid_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+
+       uint32_t apsel, apselsave, apid;
+       int retval;
+
+       apselsave = dap->apsel;
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = dap->apsel;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               /* AP address is in bits 31:24 of DP_SELECT */
+               if (apsel >= 256)
+                       return ERROR_INVALID_ARGUMENTS;
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       if (apselsave != apsel)
+               dap_ap_select(dap, apsel);
+
+       retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid);
+       retval = dap_run(dap);
+       if (retval != ERROR_OK)
+               return retval;
+
+       command_print(CMD_CTX, "0x%8.8" PRIx32, apid);
+       if (apselsave != apsel)
+               dap_ap_select(dap, apselsave);
+
+       return retval;
+}
+
+static const struct command_registration dap_commands[] = {
+       {
+               .name = "info",
+               .handler = handle_dap_info_command,
+               .mode = COMMAND_EXEC,
+               .help = "display ROM table for MEM-AP "
+                       "(default currently selected AP)",
+               .usage = "[ap_num]",
+       },
+       {
+               .name = "apsel",
+               .handler = dap_apsel_command,
+               .mode = COMMAND_EXEC,
+               .help = "Set the currently selected AP (default 0) "
+                       "and display the result",
+               .usage = "[ap_num]",
+       },
+       {
+               .name = "apid",
+               .handler = dap_apid_command,
+               .mode = COMMAND_EXEC,
+               .help = "return ID register from AP "
+                       "(default currently selected AP)",
+               .usage = "[ap_num]",
+       },
+       {
+               .name = "baseaddr",
+               .handler = dap_baseaddr_command,
+               .mode = COMMAND_EXEC,
+               .help = "return debug base address from MEM-AP "
+                       "(default currently selected AP)",
+               .usage = "[ap_num]",
+       },
+       {
+               .name = "memaccess",
+               .handler = dap_memaccess_command,
+               .mode = COMMAND_EXEC,
+               .help = "set/get number of extra tck for MEM-AP memory "
+                       "bus access [0-255]",
+               .usage = "[cycles]",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+const struct command_registration dap_command_handlers[] = {
+       {
+               .name = "dap",
+               .mode = COMMAND_EXEC,
+               .help = "DAP command group",
+               .chain = dap_commands,
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+
+/*
+ * This represents the bits which must be sent out on TMS/SWDIO to
+ * switch a DAP implemented using an SWJ-DP module into SWD mode.
+ * These bits are stored (and transmitted) LSB-first.
+ *
+ * See the DAP-Lite specification, section 2.2.5 for information
+ * about making the debug link select SWD or JTAG.  (Similar info
+ * is in a few other ARM documents.)
+ */
+static const uint8_t jtag2swd_bitseq[] = {
+       /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
+        * putting both JTAG and SWD logic into reset state.
+        */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* Switching sequence enables SWD and disables JTAG
+        * NOTE: bits in the DP's IDCODE may expose the need for
+        * an old/deprecated sequence (0xb6 0xed).
+        */
+       0x9e, 0xe7,
+       /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
+        * putting both JTAG and SWD logic into reset state.
+        */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+/**
+ * Put the debug link into SWD mode, if the target supports it.
+ * The link's initial mode may be either JTAG (for example,
+ * with SWJ-DP after reset) or SWD.
+ *
+ * @param target Enters SWD mode (if possible).
+ *
+ * Note that targets using the JTAG-DP do not support SWD, and that
+ * some targets which could otherwise support it may have have been
+ * configured to disable SWD signaling
+ *
+ * @return ERROR_OK or else a fault code.
+ */
+int dap_to_swd(struct target *target)
+{
+       int retval;
+
+       LOG_DEBUG("Enter SWD mode");
+
+       /* REVISIT it's nasty to need to make calls to a "jtag"
+        * subsystem if the link isn't in JTAG mode...
+        */
+
+       retval =  jtag_add_tms_seq(8 * sizeof(jtag2swd_bitseq),
+                       jtag2swd_bitseq, TAP_INVALID);
+       if (retval == ERROR_OK)
+               retval = jtag_execute_queue();
+
+       /* REVISIT set up the DAP's ops vector for SWD mode. */
+
+       return retval;
+}
+
diff --git a/src/target/arm_adi_v5.c~ b/src/target/arm_adi_v5.c~
new file mode 100644 (file)
index 0000000..708e858
--- /dev/null
@@ -0,0 +1,1981 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Magnus Lundin                                   *
+ *   lundin@mlu.mine.nu                                                    *
+ *                                                                         *
+ *   Copyright (C) 2008 by Spencer Oliver                                  *
+ *   spen@spen-soft.co.uk                                                  *
+ *                                                                         *
+ *   Copyright (C) 2009 by Oyvind Harboe                                   *
+ *   oyvind.harboe@zylin.com                                               *
+ *                                                                         *
+ *   Copyright (C) 2009-2010 by David Brownell                             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+
+/**
+ * @file
+ * This file implements support for the ARM Debug Interface version 5 (ADIv5)
+ * debugging architecture.  Compared with previous versions, this includes
+ * a low pin-count Serial Wire Debug (SWD) alternative to JTAG for message
+ * transport, and focusses on memory mapped resources as defined by the
+ * CoreSight architecture.
+ *
+ * A key concept in ADIv5 is the Debug Access Port, or DAP.  A DAP has two
+ * basic components:  a Debug Port (DP) transporting messages to and from a
+ * debugger, and an Access Port (AP) accessing resources.  Three types of DP
+ * are defined.  One uses only JTAG for communication, and is called JTAG-DP.
+ * One uses only SWD for communication, and is called SW-DP.  The third can
+ * use either SWD or JTAG, and is called SWJ-DP.  The most common type of AP
+ * is used to access memory mapped resources and is called a MEM-AP.  Also a
+ * JTAG-AP is also defined, bridging to JTAG resources; those are uncommon.
+ *
+ * This programming interface allows DAP pipelined operations through a
+ * transaction queue.  This primarily affects AP operations (such as using
+ * a MEM-AP to access memory or registers).  If the current transaction has
+ * not finished by the time the next one must begin, and the ORUNDETECT bit
+ * is set in the DP_CTRL_STAT register, the SSTICKYORUN status is set and
+ * further AP operations will fail.  There are two basic methods to avoid
+ * such overrun errors.  One involves polling for status instead of using
+ * transaction piplining.  The other involves adding delays to ensure the
+ * AP has enough time to complete one operation before starting the next
+ * one.  (For JTAG these delays are controlled by memaccess_tck.)
+ */
+
+/*
+ * Relevant specifications from ARM include:
+ *
+ * ARM(tm) Debug Interface v5 Architecture Specification    ARM IHI 0031A
+ * CoreSight(tm) v1.0 Architecture Specification            ARM IHI 0029B
+ *
+ * CoreSight(tm) DAP-Lite TRM, ARM DDI 0316D
+ * Cortex-M3(tm) TRM, ARM DDI 0337G
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "arm.h"
+#include "arm_adi_v5.h"
+#include <helper/time_support.h>
+
+
+/* ARM ADI Specification requires at least 10 bits used for TAR autoincrement  */
+
+/*
+       uint32_t tar_block_size(uint32_t address)
+       Return the largest block starting at address that does not cross a tar block size alignment boundary
+*/
+static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address)
+{
+       return (tar_autoincr_block - ((tar_autoincr_block - 1) & address)) >> 2;
+}
+
+/***************************************************************************
+ *                                                                         *
+<<<<<<< HEAD:src/target/arm_adi_v5.c
+=======
+ * DPACC and APACC scanchain access through JTAG-DP                        *
+ *                                                                         *
+***************************************************************************/
+
+/**
+ * Scan DPACC or APACC using target ordered uint8_t buffers.  No endianness
+ * conversions are performed.  See section 4.4.3 of the ADIv5 spec, which
+ * discusses operations which access these registers.
+ *
+ * Note that only one scan is performed.  If RnW is set, a separate scan
+ * will be needed to collect the data which was read; the "invalue" collects
+ * the posted result of a preceding operation, not the current one.
+ *
+ * @param swjdp the DAP
+ * @param instr JTAG_DP_APACC (AP access) or JTAG_DP_DPACC (DP access)
+ * @param reg_addr two significant bits; A[3:2]; for APACC access, the
+ *     SELECT register has more addressing bits.
+ * @param RnW false iff outvalue will be written to the DP or AP
+ * @param outvalue points to a 32-bit (little-endian) integer
+ * @param invalue NULL, or points to a 32-bit (little-endian) integer
+ * @param ack points to where the three bit JTAG_ACK_* code will be stored
+ */
+static int adi_jtag_dp_scan(struct adiv5_dap *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint8_t *outvalue, uint8_t *invalue, uint8_t *ack)
+{
+       struct arm_jtag *jtag_info = swjdp->jtag_info;
+       struct scan_field fields[2];
+       uint8_t out_addr_buf;
+
+       jtag_set_end_state(TAP_IDLE);
+       arm_jtag_set_instr(jtag_info, instr, NULL);
+
+       /* Scan out a read or write operation using some DP or AP register.
+        * For APACC access with any sticky error flag set, this is discarded.
+        */
+       fields[0].num_bits = 3;
+       buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr >> 1) & 0x6) | (RnW & 0x1));
+       fields[0].out_value = &out_addr_buf;
+       fields[0].in_value = ack;
+
+       /* NOTE: if we receive JTAG_ACK_WAIT, the previous operation did not
+        * complete; data we write is discarded, data we read is unpredictable.
+        * When overrun detect is active, STICKYORUN is set.
+        */
+
+       fields[1].num_bits = 32;
+       fields[1].out_value = outvalue;
+       fields[1].in_value = invalue;
+
+       jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
+
+       /* Add specified number of tck clocks after starting memory bus
+        * access, giving the hardware time to complete the access.
+        * They provide more time for the (MEM) AP to complete the read ...
+        * See "Minimum Response Time" for JTAG-DP, in the ADIv5 spec.
+        */
+       if ((instr == JTAG_DP_APACC)
+                       && ((reg_addr == AP_REG_DRW)
+                               || ((reg_addr & 0xF0) == AP_REG_BD0))
+                       && (swjdp->memaccess_tck != 0))
+               jtag_add_runtest(swjdp->memaccess_tck,
+                               TAP_IDLE);
+
+       return jtag_get_error();
+}
+
+/**
+ * Scan DPACC or APACC out and in from host ordered uint32_t buffers.
+ * This is exactly like adi_jtag_dp_scan(), except that endianness
+ * conversions are performed (so the types of invalue and outvalue
+ * must be different).
+ */
+static int adi_jtag_dp_scan_u32(struct adiv5_dap *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint32_t outvalue, uint32_t *invalue, uint8_t *ack)
+{
+       uint8_t out_value_buf[4];
+       int retval;
+
+       buf_set_u32(out_value_buf, 0, 32, outvalue);
+
+       retval = adi_jtag_dp_scan(swjdp, instr, reg_addr, RnW,
+                       out_value_buf, (uint8_t *)invalue, ack);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (invalue)
+               jtag_add_callback(arm_le_to_h_u32,
+                               (jtag_callback_data_t) invalue);
+
+       return retval;
+}
+
+/**
+ * Utility to write AP registers.
+ */
+static inline int adi_jtag_ap_write_check(struct adiv5_dap *dap,
+               uint8_t reg_addr, uint8_t *outvalue)
+{
+       return adi_jtag_dp_scan(dap, JTAG_DP_APACC, reg_addr, DPAP_WRITE,
+                       outvalue, NULL, NULL);
+}
+
+static int adi_jtag_scan_inout_check_u32(struct adiv5_dap *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint32_t outvalue, uint32_t *invalue)
+{
+       int retval;
+
+       /* Issue the read or write */
+       retval = adi_jtag_dp_scan_u32(swjdp, instr, reg_addr,
+                       RnW, outvalue, NULL, NULL);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* For reads,  collect posted value; RDBUFF has no other effect.
+        * Assumes read gets acked with OK/FAULT, and CTRL_STAT says "OK".
+        */
+       if ((RnW == DPAP_READ) && (invalue != NULL))
+               retval = adi_jtag_dp_scan_u32(swjdp, JTAG_DP_DPACC,
+                               DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack);
+       return retval;
+}
+
+static int jtagdp_transaction_endcheck(struct adiv5_dap *swjdp)
+{
+       int retval;
+       uint32_t ctrlstat;
+
+       /* too expensive to call keep_alive() here */
+
+#if 0
+       /* Danger!!!! BROKEN!!!! */
+       adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+       /* Danger!!!! BROKEN!!!! Why will jtag_execute_queue() fail here????
+       R956 introduced the check on return value here and now Michael Schwingen reports
+       that this code no longer works....
+
+       https://lists.berlios.de/pipermail/openocd-development/2008-September/003107.html
+       */
+       if ((retval = jtag_execute_queue()) != ERROR_OK)
+       {
+               LOG_ERROR("BUG: Why does this fail the first time????");
+       }
+       /* Why??? second time it works??? */
+#endif
+
+       /* Post CTRL/STAT read; discard any previous posted read value
+        * but collect its ACK status.
+        */
+       adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+       if ((retval = jtag_execute_queue()) != ERROR_OK)
+               return retval;
+
+       swjdp->ack = swjdp->ack & 0x7;
+
+       /* common code path avoids calling timeval_ms() */
+       if (swjdp->ack != JTAG_ACK_OK_FAULT)
+       {
+               long long then = timeval_ms();
+
+               while (swjdp->ack != JTAG_ACK_OK_FAULT)
+               {
+                       if (swjdp->ack == JTAG_ACK_WAIT)
+                       {
+                               if ((timeval_ms()-then) > 1000)
+                               {
+                                       /* NOTE:  this would be a good spot
+                                        * to use JTAG_DP_ABORT.
+                                        */
+                                       LOG_WARNING("Timeout (1000ms) waiting "
+                                               "for ACK=OK/FAULT "
+                                               "in JTAG-DP transaction");
+                                       return ERROR_JTAG_DEVICE_ERROR;
+                               }
+                       }
+                       else
+                       {
+                               LOG_WARNING("Invalid ACK %#x "
+                                               "in JTAG-DP transaction",
+                                               swjdp->ack);
+                               return ERROR_JTAG_DEVICE_ERROR;
+                       }
+
+                       adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+                       if ((retval = dap_run(swjdp)) != ERROR_OK)
+                               return retval;
+                       swjdp->ack = swjdp->ack & 0x7;
+               }
+       }
+
+       /* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */
+
+       /* Check for STICKYERR and STICKYORUN */
+       if (ctrlstat & (SSTICKYORUN | SSTICKYERR))
+       {
+               LOG_DEBUG("jtag-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
+               /* Check power to debug regions */
+               if ((ctrlstat & 0xf0000000) != 0xf0000000)
+                        ahbap_debugport_init(swjdp);
+               else
+               {
+                       uint32_t mem_ap_csw, mem_ap_tar;
+
+                       /* Maybe print information about last intended
+                        * MEM-AP access; but not if autoincrementing.
+                        * *Real* CSW and TAR values are always shown.
+                        */
+                       if (swjdp->ap_tar_value != (uint32_t) -1)
+                               LOG_DEBUG("MEM-AP Cached values: "
+                                       "ap_bank 0x%" PRIx32
+                                       ", ap_csw 0x%" PRIx32
+                                       ", ap_tar 0x%" PRIx32,
+                                       swjdp->ap_bank_value,
+                                       swjdp->ap_csw_value,
+                                       swjdp->ap_tar_value);
+
+                       if (ctrlstat & SSTICKYORUN)
+                               LOG_ERROR("JTAG-DP OVERRUN - check clock, "
+                                       "memaccess, or reduce jtag speed");
+
+                       if (ctrlstat & SSTICKYERR)
+                               LOG_ERROR("JTAG-DP STICKY ERROR");
+
+                       /* Clear Sticky Error Bits */
+                       adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                                       DP_CTRL_STAT, DPAP_WRITE,
+                                       swjdp->dp_ctrl_stat | SSTICKYORUN
+                                               | SSTICKYERR, NULL);
+                       adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+                       if ((retval = dap_run(swjdp)) != ERROR_OK)
+                               return retval;
+
+                       LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
+
+                       retval = dap_queue_ap_read(swjdp,
+                                       AP_REG_CSW, &mem_ap_csw);
+                       if (retval != ERROR_OK)
+                               return retval;
+
+                       retval = dap_queue_ap_read(swjdp,
+                                       AP_REG_TAR, &mem_ap_tar);
+                       if (retval != ERROR_OK)
+                               return retval;
+
+                       if ((retval = dap_run(swjdp)) != ERROR_OK)
+                               return retval;
+                       LOG_ERROR("MEM_AP_CSW 0x%" PRIx32 ", MEM_AP_TAR 0x%"
+                                       PRIx32, mem_ap_csw, mem_ap_tar);
+
+               }
+               if ((retval = dap_run(swjdp)) != ERROR_OK)
+                       return retval;
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+
+       return ERROR_OK;
+}
+
+/***************************************************************************
+ *                                                                         *
+>>>>>>> jtag: cut down on usage of unintended modification of global end state:src/target/arm_adi_v5.c
+ * DP and MEM-AP  register access  through APACC and DPACC                 *
+ *                                                                         *
+***************************************************************************/
+
+/**
+ * Select one of the APs connected to the specified DAP.  The
+ * selection is implicitly used with future AP transactions.
+ * This is a NOP if the specified AP is already selected.
+ *
+ * @param swjdp The DAP
+ * @param apsel Number of the AP to (implicitly) use with further
+ *     transactions.  This normally identifies a MEM-AP.
+ */
+void dap_ap_select(struct adiv5_dap *swjdp,uint8_t apsel)
+{
+       uint32_t select = (apsel << 24) & 0xFF000000;
+
+       if (select != swjdp->apsel)
+       {
+               swjdp->apsel = select;
+               /* Switching AP invalidates cached values.
+                * Values MUST BE UPDATED BEFORE AP ACCESS.
+                */
+               swjdp->ap_bank_value = -1;
+               swjdp->ap_csw_value = -1;
+               swjdp->ap_tar_value = -1;
+       }
+}
+
+/**
+ * Queue transactions setting up transfer parameters for the
+ * currently selected MEM-AP.
+ *
+ * Subsequent transfers using registers like AP_REG_DRW or AP_REG_BD2
+ * initiate data reads or writes using memory or peripheral addresses.
+ * If the CSW is configured for it, the TAR may be automatically
+ * incremented after each transfer.
+ *
+ * @todo Rename to reflect it being specifically a MEM-AP function.
+ *
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param csw MEM-AP Control/Status Word (CSW) register to assign.  If this
+ *     matches the cached value, the register is not changed.
+ * @param tar MEM-AP Transfer Address Register (TAR) to assign.  If this
+ *     matches the cached address, the register is not changed.
+ *
+ * @return ERROR_OK if the transaction was properly queued, else a fault code.
+ */
+int dap_setup_accessport(struct adiv5_dap *swjdp, uint32_t csw, uint32_t tar)
+{
+       int retval;
+
+       csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT;
+       if (csw != swjdp->ap_csw_value)
+       {
+               /* LOG_DEBUG("DAP: Set CSW %x",csw); */
+               retval = dap_queue_ap_write(swjdp, AP_REG_CSW, csw);
+               if (retval != ERROR_OK)
+                       return retval;
+               swjdp->ap_csw_value = csw;
+       }
+       if (tar != swjdp->ap_tar_value)
+       {
+               /* LOG_DEBUG("DAP: Set TAR %x",tar); */
+               retval = dap_queue_ap_write(swjdp, AP_REG_TAR, tar);
+               if (retval != ERROR_OK)
+                       return retval;
+               swjdp->ap_tar_value = tar;
+       }
+       /* Disable TAR cache when autoincrementing */
+       if (csw & CSW_ADDRINC_MASK)
+               swjdp->ap_tar_value = -1;
+       return ERROR_OK;
+}
+
+/**
+ * Asynchronous (queued) read of a word from memory or a system register.
+ *
+ * @param swjdp The DAP connected to the MEM-AP performing the read.
+ * @param address Address of the 32-bit word to read; it must be
+ *     readable by the currently selected MEM-AP.
+ * @param value points to where the word will be stored when the
+ *     transaction queue is flushed (assuming no errors).
+ *
+ * @return ERROR_OK for success.  Otherwise a fault code.
+ */
+int mem_ap_read_u32(struct adiv5_dap *swjdp, uint32_t address,
+               uint32_t *value)
+{
+       int retval;
+
+       /* Use banked addressing (REG_BDx) to avoid some link traffic
+        * (updating TAR) when reading several consecutive addresses.
+        */
+       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF,
+                       address & 0xFFFFFFF0);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return dap_queue_ap_read(swjdp, AP_REG_BD0 | (address & 0xC), value);
+}
+
+/**
+ * Synchronous read of a word from memory or a system register.
+ * As a side effect, this flushes any queued transactions.
+ *
+ * @param swjdp The DAP connected to the MEM-AP performing the read.
+ * @param address Address of the 32-bit word to read; it must be
+ *     readable by the currently selected MEM-AP.
+ * @param value points to where the result will be stored.
+ *
+ * @return ERROR_OK for success; *value holds the result.
+ * Otherwise a fault code.
+ */
+int mem_ap_read_atomic_u32(struct adiv5_dap *swjdp, uint32_t address,
+               uint32_t *value)
+{
+       int retval;
+
+       retval = mem_ap_read_u32(swjdp, address, value);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return dap_run(swjdp);
+}
+
+/**
+ * Asynchronous (queued) write of a word to memory or a system register.
+ *
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param address Address to be written; it must be writable by
+ *     the currently selected MEM-AP.
+ * @param value Word that will be written to the address when transaction
+ *     queue is flushed (assuming no errors).
+ *
+ * @return ERROR_OK for success.  Otherwise a fault code.
+ */
+int mem_ap_write_u32(struct adiv5_dap *swjdp, uint32_t address,
+               uint32_t value)
+{
+       int retval;
+
+       /* Use banked addressing (REG_BDx) to avoid some link traffic
+        * (updating TAR) when writing several consecutive addresses.
+        */
+       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF,
+                       address & 0xFFFFFFF0);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return dap_queue_ap_write(swjdp, AP_REG_BD0 | (address & 0xC),
+                       value);
+}
+
+/**
+ * Synchronous write of a word to memory or a system register.
+ * As a side effect, this flushes any queued transactions.
+ *
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param address Address to be written; it must be writable by
+ *     the currently selected MEM-AP.
+ * @param value Word that will be written.
+ *
+ * @return ERROR_OK for success; the data was written.  Otherwise a fault code.
+ */
+int mem_ap_write_atomic_u32(struct adiv5_dap *swjdp, uint32_t address,
+               uint32_t value)
+{
+       int retval = mem_ap_write_u32(swjdp, address, value);
+
+       if (retval != ERROR_OK)
+               return retval;
+
+       return dap_run(swjdp);
+}
+
+/*****************************************************************************
+*                                                                            *
+* mem_ap_write_buf(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) *
+*                                                                            *
+* Write a buffer in target order (little endian)                             *
+*                                                                            *
+*****************************************************************************/
+int mem_ap_write_buf_u32(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address)
+{
+       int wcount, blocksize, writecount, errorcount = 0, retval = ERROR_OK;
+       uint32_t adr = address;
+       uint8_t* pBuffer = buffer;
+
+       count >>= 2;
+       wcount = count;
+
+       /* if we have an unaligned access - reorder data */
+       if (adr & 0x3u)
+       {
+               for (writecount = 0; writecount < count; writecount++)
+               {
+                       int i;
+                       uint32_t outvalue;
+                       memcpy(&outvalue, pBuffer, sizeof(uint32_t));
+
+                       for (i = 0; i < 4; i++)
+                       {
+                               *((uint8_t*)pBuffer + (adr & 0x3)) = outvalue;
+                               outvalue >>= 8;
+                               adr++;
+                       }
+                       pBuffer += sizeof(uint32_t);
+               }
+       }
+
+       while (wcount > 0)
+       {
+               /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               /* handle unaligned data at 4k boundary */
+               if (blocksize == 0)
+                       blocksize = 1;
+
+               dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, address);
+
+               for (writecount = 0; writecount < blocksize; writecount++)
+               {
+                       retval = dap_queue_ap_write(swjdp, AP_REG_DRW,
+                               *(uint32_t *) (buffer + 4 * writecount));
+                       if (retval != ERROR_OK)
+                               break;
+               }
+
+               if (dap_run(swjdp) == ERROR_OK)
+               {
+                       wcount = wcount - blocksize;
+                       address = address + 4 * blocksize;
+                       buffer = buffer + 4 * blocksize;
+               }
+               else
+               {
+                       errorcount++;
+               }
+
+               if (errorcount > 1)
+               {
+                       LOG_WARNING("Block write error address 0x%" PRIx32 ", wcount 0x%x", address, wcount);
+                       /* REVISIT return the *actual* fault code */
+                       return ERROR_JTAG_DEVICE_ERROR;
+               }
+       }
+
+       return retval;
+}
+
+static int mem_ap_write_buf_packed_u16(struct adiv5_dap *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
+{
+       int retval = ERROR_OK;
+       int wcount, blocksize, writecount, i;
+
+       wcount = count >> 1;
+
+       while (wcount > 0)
+       {
+               int nbytes;
+
+               /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               /* handle unaligned data at 4k boundary */
+               if (blocksize == 0)
+                       blocksize = 1;
+
+               dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_PACKED, address);
+               writecount = blocksize;
+
+               do
+               {
+                       nbytes = MIN((writecount << 1), 4);
+
+                       if (nbytes < 4)
+                       {
+                               if (mem_ap_write_buf_u16(swjdp, buffer,
+                                               nbytes, address) != ERROR_OK)
+                               {
+                                       LOG_WARNING("Block write error address "
+                                               "0x%" PRIx32 ", count 0x%x",
+                                               address, count);
+                                       return ERROR_JTAG_DEVICE_ERROR;
+                               }
+
+                               address += nbytes >> 1;
+                       }
+                       else
+                       {
+                               uint32_t outvalue;
+                               memcpy(&outvalue, buffer, sizeof(uint32_t));
+
+                               for (i = 0; i < nbytes; i++)
+                               {
+                                       *((uint8_t*)buffer + (address & 0x3)) = outvalue;
+                                       outvalue >>= 8;
+                                       address++;
+                               }
+
+                               memcpy(&outvalue, buffer, sizeof(uint32_t));
+                               retval = dap_queue_ap_write(swjdp,
+                                               AP_REG_DRW, outvalue);
+                               if (retval != ERROR_OK)
+                                       break;
+
+                               if (dap_run(swjdp) != ERROR_OK)
+                               {
+                                       LOG_WARNING("Block write error address "
+                                               "0x%" PRIx32 ", count 0x%x",
+                                               address, count);
+                                       /* REVISIT return *actual* fault code */
+                                       return ERROR_JTAG_DEVICE_ERROR;
+                               }
+                       }
+
+                       buffer += nbytes >> 1;
+                       writecount -= nbytes >> 1;
+
+               } while (writecount);
+               wcount -= blocksize;
+       }
+
+       return retval;
+}
+
+int mem_ap_write_buf_u16(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address)
+{
+       int retval = ERROR_OK;
+
+       if (count >= 4)
+               return mem_ap_write_buf_packed_u16(swjdp, buffer, count, address);
+
+       while (count > 0)
+       {
+               dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
+               uint16_t svalue;
+               memcpy(&svalue, buffer, sizeof(uint16_t));
+               uint32_t outvalue = (uint32_t)svalue << 8 * (address & 0x3);
+               retval = dap_queue_ap_write(swjdp, AP_REG_DRW, outvalue);
+               if (retval != ERROR_OK)
+                       break;
+
+               retval = dap_run(swjdp);
+               if (retval != ERROR_OK)
+                       break;
+
+               count -= 2;
+               address += 2;
+               buffer += 2;
+       }
+
+       return retval;
+}
+
+static int mem_ap_write_buf_packed_u8(struct adiv5_dap *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
+{
+       int retval = ERROR_OK;
+       int wcount, blocksize, writecount, i;
+
+       wcount = count;
+
+       while (wcount > 0)
+       {
+               int nbytes;
+
+               /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_PACKED, address);
+               writecount = blocksize;
+
+               do
+               {
+                       nbytes = MIN(writecount, 4);
+
+                       if (nbytes < 4)
+                       {
+                               if (mem_ap_write_buf_u8(swjdp, buffer, nbytes, address) != ERROR_OK)
+                               {
+                                       LOG_WARNING("Block write error address "
+                                               "0x%" PRIx32 ", count 0x%x",
+                                               address, count);
+                                       return ERROR_JTAG_DEVICE_ERROR;
+                               }
+
+                               address += nbytes;
+                       }
+                       else
+                       {
+                               uint32_t outvalue;
+                               memcpy(&outvalue, buffer, sizeof(uint32_t));
+
+                               for (i = 0; i < nbytes; i++)
+                               {
+                                       *((uint8_t*)buffer + (address & 0x3)) = outvalue;
+                                       outvalue >>= 8;
+                                       address++;
+                               }
+
+                               memcpy(&outvalue, buffer, sizeof(uint32_t));
+                               retval = dap_queue_ap_write(swjdp,
+                                               AP_REG_DRW, outvalue);
+                               if (retval != ERROR_OK)
+                                       break;
+
+                               if (dap_run(swjdp) != ERROR_OK)
+                               {
+                                       LOG_WARNING("Block write error address "
+                                               "0x%" PRIx32 ", count 0x%x",
+                                               address, count);
+                                       /* REVISIT return *actual* fault code */
+                                       return ERROR_JTAG_DEVICE_ERROR;
+                               }
+                       }
+
+                       buffer += nbytes;
+                       writecount -= nbytes;
+
+               } while (writecount);
+               wcount -= blocksize;
+       }
+
+       return retval;
+}
+
+int mem_ap_write_buf_u8(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address)
+{
+       int retval = ERROR_OK;
+
+       if (count >= 4)
+               return mem_ap_write_buf_packed_u8(swjdp, buffer, count, address);
+
+       while (count > 0)
+       {
+               dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
+               uint32_t outvalue = (uint32_t)*buffer << 8 * (address & 0x3);
+               retval = dap_queue_ap_write(swjdp, AP_REG_DRW, outvalue);
+               if (retval != ERROR_OK)
+                       break;
+
+               retval = dap_run(swjdp);
+               if (retval != ERROR_OK)
+                       break;
+
+               count--;
+               address++;
+               buffer++;
+       }
+
+       return retval;
+}
+
+/* FIXME don't import ... this is a temporary workaround for the
+ * mem_ap_read_buf_u32() mess, until it's no longer JTAG-specific.
+ */
+extern int adi_jtag_dp_scan(struct adiv5_dap *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint8_t *outvalue, uint8_t *invalue, uint8_t *ack);
+
+/**
+ * Synchronously read a block of 32-bit words into a buffer
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param buffer where the words will be stored (in host byte order).
+ * @param count How many words to read.
+ * @param address Memory address from which to read words; all the
+ *     words must be readable by the currently selected MEM-AP.
+ */
+int mem_ap_read_buf_u32(struct adiv5_dap *swjdp, uint8_t *buffer,
+               int count, uint32_t address)
+{
+       int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK;
+       uint32_t adr = address;
+       uint8_t* pBuffer = buffer;
+
+       count >>= 2;
+       wcount = count;
+
+       while (wcount > 0)
+       {
+               /* Adjust to read blocks within boundaries aligned to the
+                * TAR autoincrement size (at least 2^10).  Autoincrement
+                * mode avoids an extra per-word roundtrip to update TAR.
+                */
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block,
+                               address);
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               /* handle unaligned data at 4k boundary */
+               if (blocksize == 0)
+                       blocksize = 1;
+
+               dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE,
+                               address);
+
+               /* FIXME remove these three calls to adi_jtag_dp_scan(),
+                * so this routine becomes transport-neutral.  Be careful
+                * not to cause performance problems with JTAG; would it
+                * suffice to loop over dap_queue_ap_read(), or would that
+                * be slower when JTAG is the chosen transport?
+                */
+
+               /* Scan out first read */
+               adi_jtag_dp_scan(swjdp, JTAG_DP_APACC, AP_REG_DRW,
+                               DPAP_READ, 0, NULL, NULL);
+               for (readcount = 0; readcount < blocksize - 1; readcount++)
+               {
+                       /* Scan out next read; scan in posted value for the
+                        * previous one.  Assumes read is acked "OK/FAULT",
+                        * and CTRL_STAT says that meant "OK".
+                        */
+                       adi_jtag_dp_scan(swjdp, JTAG_DP_APACC, AP_REG_DRW,
+                                       DPAP_READ, 0, buffer + 4 * readcount,
+                                       &swjdp->ack);
+               }
+
+               /* Scan in last posted value; RDBUFF has no other effect,
+                * assuming ack is OK/FAULT and CTRL_STAT says "OK".
+                */
+               adi_jtag_dp_scan(swjdp, JTAG_DP_DPACC, DP_RDBUFF,
+                               DPAP_READ, 0, buffer + 4 * readcount,
+                               &swjdp->ack);
+               if (dap_run(swjdp) == ERROR_OK)
+               {
+                       wcount = wcount - blocksize;
+                       address += 4 * blocksize;
+                       buffer += 4 * blocksize;
+               }
+               else
+               {
+                       errorcount++;
+               }
+
+               if (errorcount > 1)
+               {
+                       LOG_WARNING("Block read error address 0x%" PRIx32
+                               ", count 0x%x", address, count);
+                       /* REVISIT return the *actual* fault code */
+                       return ERROR_JTAG_DEVICE_ERROR;
+               }
+       }
+
+       /* if we have an unaligned access - reorder data */
+       if (adr & 0x3u)
+       {
+               for (readcount = 0; readcount < count; readcount++)
+               {
+                       int i;
+                       uint32_t data;
+                       memcpy(&data, pBuffer, sizeof(uint32_t));
+
+                       for (i = 0; i < 4; i++)
+                       {
+                               *((uint8_t*)pBuffer) =
+                                               (data >> 8 * (adr & 0x3));
+                               pBuffer++;
+                               adr++;
+                       }
+               }
+       }
+
+       return retval;
+}
+
+static int mem_ap_read_buf_packed_u16(struct adiv5_dap *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
+{
+       uint32_t invalue;
+       int retval = ERROR_OK;
+       int wcount, blocksize, readcount, i;
+
+       wcount = count >> 1;
+
+       while (wcount > 0)
+       {
+               int nbytes;
+
+               /* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_PACKED, address);
+
+               /* handle unaligned data at 4k boundary */
+               if (blocksize == 0)
+                       blocksize = 1;
+               readcount = blocksize;
+
+               do
+               {
+                       retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue);
+                       if (dap_run(swjdp) != ERROR_OK)
+                       {
+                               LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
+                               /* REVISIT return the *actual* fault code */
+                               return ERROR_JTAG_DEVICE_ERROR;
+                       }
+
+                       nbytes = MIN((readcount << 1), 4);
+
+                       for (i = 0; i < nbytes; i++)
+                       {
+                               *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
+                               buffer++;
+                               address++;
+                       }
+
+                       readcount -= (nbytes >> 1);
+               } while (readcount);
+               wcount -= blocksize;
+       }
+
+       return retval;
+}
+
+/**
+ * Synchronously read a block of 16-bit halfwords into a buffer
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param buffer where the halfwords will be stored (in host byte order).
+ * @param count How many halfwords to read.
+ * @param address Memory address from which to read words; all the
+ *     words must be readable by the currently selected MEM-AP.
+ */
+int mem_ap_read_buf_u16(struct adiv5_dap *swjdp, uint8_t *buffer,
+               int count, uint32_t address)
+{
+       uint32_t invalue, i;
+       int retval = ERROR_OK;
+
+       if (count >= 4)
+               return mem_ap_read_buf_packed_u16(swjdp, buffer, count, address);
+
+       while (count > 0)
+       {
+               dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
+               retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue);
+               if (retval != ERROR_OK)
+                       break;
+
+               retval = dap_run(swjdp);
+               if (retval != ERROR_OK)
+                       break;
+
+               if (address & 0x1)
+               {
+                       for (i = 0; i < 2; i++)
+                       {
+                               *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
+                               buffer++;
+                               address++;
+                       }
+               }
+               else
+               {
+                       uint16_t svalue = (invalue >> 8 * (address & 0x3));
+                       memcpy(buffer, &svalue, sizeof(uint16_t));
+                       address += 2;
+                       buffer += 2;
+               }
+               count -= 2;
+       }
+
+       return retval;
+}
+
+/* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
+ * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
+ *
+ * The solution is to arrange for a large out/in scan in this loop and
+ * and convert data afterwards.
+ */
+static int mem_ap_read_buf_packed_u8(struct adiv5_dap *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
+{
+       uint32_t invalue;
+       int retval = ERROR_OK;
+       int wcount, blocksize, readcount, i;
+
+       wcount = count;
+
+       while (wcount > 0)
+       {
+               int nbytes;
+
+               /* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+
+               if (wcount < blocksize)
+                       blocksize = wcount;
+
+               dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_PACKED, address);
+               readcount = blocksize;
+
+               do
+               {
+                       retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue);
+                       if (dap_run(swjdp) != ERROR_OK)
+                       {
+                               LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
+                               /* REVISIT return the *actual* fault code */
+                               return ERROR_JTAG_DEVICE_ERROR;
+                       }
+
+                       nbytes = MIN(readcount, 4);
+
+                       for (i = 0; i < nbytes; i++)
+                       {
+                               *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
+                               buffer++;
+                               address++;
+                       }
+
+                       readcount -= nbytes;
+               } while (readcount);
+               wcount -= blocksize;
+       }
+
+       return retval;
+}
+
+/**
+ * Synchronously read a block of bytes into a buffer
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param buffer where the bytes will be stored.
+ * @param count How many bytes to read.
+ * @param address Memory address from which to read data; all the
+ *     data must be readable by the currently selected MEM-AP.
+ */
+int mem_ap_read_buf_u8(struct adiv5_dap *swjdp, uint8_t *buffer,
+               int count, uint32_t address)
+{
+       uint32_t invalue;
+       int retval = ERROR_OK;
+
+       if (count >= 4)
+               return mem_ap_read_buf_packed_u8(swjdp, buffer, count, address);
+
+       while (count > 0)
+       {
+               dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
+               retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue);
+               retval = dap_run(swjdp);
+               if (retval != ERROR_OK)
+                       break;
+
+               *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
+               count--;
+               address++;
+               buffer++;
+       }
+
+       return retval;
+}
+
+/*--------------------------------------------------------------------------*/
+
+<<<<<<< HEAD:src/target/arm_adi_v5.c
+=======
+static int jtag_idcode_q_read(struct adiv5_dap *dap,
+               uint8_t *ack, uint32_t *data)
+{
+       struct arm_jtag *jtag_info = dap->jtag_info;
+       int retval;
+       struct scan_field fields[1];
+
+       jtag_set_end_state(TAP_IDLE);
+
+       /* This is a standard JTAG operation -- no DAP tweakage */
+       retval = arm_jtag_set_instr(jtag_info, JTAG_DP_IDCODE, NULL);
+       if (retval != ERROR_OK)
+               return retval;
+
+       fields[0].num_bits = 32;
+       fields[0].out_value = NULL;
+       fields[0].in_value = (void *) data;
+
+       jtag_add_dr_scan(jtag_info->tap, 1, fields, TAP_IDLE);
+       retval = jtag_get_error();
+       if (retval != ERROR_OK)
+               return retval;
+
+       jtag_add_callback(arm_le_to_h_u32,
+                       (jtag_callback_data_t) data);
+
+       return retval;
+}
+
+static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
+               uint32_t *data)
+{
+       return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+                       reg, DPAP_READ, 0, data);
+}
+
+static int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg,
+               uint32_t data)
+{
+       return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+                       reg, DPAP_WRITE, data, NULL);
+}
+
+/** Select the AP register bank matching bits 7:4 of reg. */
+static int jtag_ap_q_bankselect(struct adiv5_dap *dap, unsigned reg)
+{
+       uint32_t select = reg & 0x000000F0;
+
+       if (select == dap->ap_bank_value)
+               return ERROR_OK;
+       dap->ap_bank_value = select;
+
+       select |= dap->apsel;
+
+       return jtag_dp_q_write(dap, DP_SELECT, select);
+}
+
+static int jtag_ap_q_read(struct adiv5_dap *dap, unsigned reg,
+               uint32_t *data)
+{
+       int retval = jtag_ap_q_bankselect(dap, reg);
+
+       if (retval != ERROR_OK)
+               return retval;
+
+       return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_APACC, reg,
+                       DPAP_READ, 0, data);
+}
+
+static int jtag_ap_q_write(struct adiv5_dap *dap, unsigned reg,
+               uint32_t data)
+{
+       uint8_t out_value_buf[4];
+
+       int retval = jtag_ap_q_bankselect(dap, reg);
+       if (retval != ERROR_OK)
+               return retval;
+>>>>>>> jtag: cut down on usage of unintended modification of global end state:src/target/arm_adi_v5.c
+
+/* FIXME don't import ... just initialize as
+ * part of DAP transport setup
+*/
+extern const struct dap_ops jtag_dp_ops;
+
+/*--------------------------------------------------------------------------*/
+
+/**
+ * Initialize a DAP.  This sets up the power domains, prepares the DP
+ * for further use, and arranges to use AP #0 for all AP operations
+ * until dap_ap-select() changes that policy.
+ *
+ * @param swjdp The DAP being initialized.
+ *
+ * @todo Rename this.  We also need an initialization scheme which account
+ * for SWD transports not just JTAG; that will need to address differences
+ * in layering.  (JTAG is useful without any debug target; but not SWD.)
+ * And this may not even use an AHB-AP ... e.g. DAP-Lite uses an APB-AP.
+ */
+int ahbap_debugport_init(struct adiv5_dap *swjdp)
+{
+       uint32_t idreg, romaddr, dummy;
+       uint32_t ctrlstat;
+       int cnt = 0;
+       int retval;
+
+       LOG_DEBUG(" ");
+
+       /* JTAG-DP or SWJ-DP, in JTAG mode */
+       swjdp->ops = &jtag_dp_ops;
+
+       /* Default MEM-AP setup.
+        *
+        * REVISIT AP #0 may be an inappropriate default for this.
+        * Should we probe, or take a hint from the caller?
+        * Presumably we can ignore the possibility of multiple APs.
+        */
+       swjdp->apsel = !0;
+       dap_ap_select(swjdp, 0);
+
+       /* DP initialization */
+
+       retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = dap_queue_dp_write(swjdp, DP_CTRL_STAT, SSTICKYERR);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy);
+       if (retval != ERROR_OK)
+               return retval;
+
+       swjdp->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
+       retval = dap_queue_dp_write(swjdp, DP_CTRL_STAT, swjdp->dp_ctrl_stat);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &ctrlstat);
+       if (retval != ERROR_OK)
+               return retval;
+       if ((retval = dap_run(swjdp)) != ERROR_OK)
+               return retval;
+
+       /* Check that we have debug power domains activated */
+       while (!(ctrlstat & CDBGPWRUPACK) && (cnt++ < 10))
+       {
+               LOG_DEBUG("DAP: wait CDBGPWRUPACK");
+               retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &ctrlstat);
+               if (retval != ERROR_OK)
+                       return retval;
+               if ((retval = dap_run(swjdp)) != ERROR_OK)
+                       return retval;
+               alive_sleep(10);
+       }
+
+       while (!(ctrlstat & CSYSPWRUPACK) && (cnt++ < 10))
+       {
+               LOG_DEBUG("DAP: wait CSYSPWRUPACK");
+               retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &ctrlstat);
+               if (retval != ERROR_OK)
+                       return retval;
+               if ((retval = dap_run(swjdp)) != ERROR_OK)
+                       return retval;
+               alive_sleep(10);
+       }
+
+       retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy);
+       if (retval != ERROR_OK)
+               return retval;
+       /* With debug power on we can activate OVERRUN checking */
+       swjdp->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT;
+       retval = dap_queue_dp_write(swjdp, DP_CTRL_STAT, swjdp->dp_ctrl_stat);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /*
+        * REVISIT this isn't actually *initializing* anything in an AP,
+        * and doesn't care if it's a MEM-AP at all (much less AHB-AP).
+        * Should it?  If the ROM address is valid, is this the right
+        * place to scan the table and do any topology detection?
+        */
+       retval = dap_queue_ap_read(swjdp, AP_REG_IDR, &idreg);
+       retval = dap_queue_ap_read(swjdp, AP_REG_BASE, &romaddr);
+
+       LOG_DEBUG("MEM-AP #%d ID Register 0x%" PRIx32
+               ", Debug ROM Address 0x%" PRIx32,
+               swjdp->apsel, idreg, romaddr);
+
+       return ERROR_OK;
+}
+
+/* CID interpretation -- see ARM IHI 0029B section 3
+ * and ARM IHI 0031A table 13-3.
+ */
+static const char *class_description[16] ={
+       "Reserved", "ROM table", "Reserved", "Reserved",
+       "Reserved", "Reserved", "Reserved", "Reserved",
+       "Reserved", "CoreSight component", "Reserved", "Peripheral Test Block",
+       "Reserved", "OptimoDE DESS",
+               "Generic IP component", "PrimeCell or System component"
+};
+
+static bool
+is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0)
+{
+       return cid3 == 0xb1 && cid2 == 0x05
+                       && ((cid1 & 0x0f) == 0) && cid0 == 0x0d;
+}
+
+static int dap_info_command(struct command_context *cmd_ctx,
+               struct adiv5_dap *swjdp, int apsel)
+{
+       int retval;
+       uint32_t dbgbase, apid;
+       int romtable_present = 0;
+       uint8_t mem_ap;
+       uint32_t apselold;
+
+       /* AP address is in bits 31:24 of DP_SELECT */
+       if (apsel >= 256)
+               return ERROR_INVALID_ARGUMENTS;
+
+       apselold = swjdp->apsel;
+       dap_ap_select(swjdp, apsel);
+       retval = dap_queue_ap_read(swjdp, AP_REG_BASE, &dbgbase);
+       retval = dap_queue_ap_read(swjdp, AP_REG_IDR, &apid);
+       retval = dap_run(swjdp);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec  */
+       mem_ap = ((apid&0x10000) && ((apid&0x0F) != 0));
+       command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid);
+       if (apid)
+       {
+               switch (apid&0x0F)
+               {
+                       case 0:
+                               command_print(cmd_ctx, "\tType is JTAG-AP");
+                               break;
+                       case 1:
+                               command_print(cmd_ctx, "\tType is MEM-AP AHB");
+                               break;
+                       case 2:
+                               command_print(cmd_ctx, "\tType is MEM-AP APB");
+                               break;
+                       default:
+                               command_print(cmd_ctx, "\tUnknown AP type");
+                               break;
+               }
+
+               /* NOTE: a MEM-AP may have a single CoreSight component that's
+                * not a ROM table ... or have no such components at all.
+                */
+               if (mem_ap)
+                       command_print(cmd_ctx, "AP BASE 0x%8.8" PRIx32,
+                                       dbgbase);
+       }
+       else
+       {
+               command_print(cmd_ctx, "No AP found at this apsel 0x%x", apsel);
+       }
+
+       romtable_present = ((mem_ap) && (dbgbase != 0xFFFFFFFF));
+       if (romtable_present)
+       {
+               uint32_t cid0,cid1,cid2,cid3,memtype,romentry;
+               uint16_t entry_offset;
+
+               /* bit 16 of apid indicates a memory access port */
+               if (dbgbase & 0x02)
+                       command_print(cmd_ctx, "\tValid ROM table present");
+               else
+                       command_print(cmd_ctx, "\tROM table in legacy format");
+
+               /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec  */
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFF0, &cid0);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFF4, &cid1);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFF8, &cid2);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFFC, &cid3);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFCC, &memtype);
+               retval = dap_run(swjdp);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
+                       command_print(cmd_ctx, "\tCID3 0x%2.2" PRIx32
+                                       ", CID2 0x%2.2" PRIx32
+                                       ", CID1 0x%2.2" PRIx32
+                                       ", CID0 0x%2.2" PRIx32,
+                                       cid3, cid2, cid1, cid0);
+               if (memtype & 0x01)
+                       command_print(cmd_ctx, "\tMEMTYPE system memory present on bus");
+               else
+                       command_print(cmd_ctx, "\tMEMTYPE System memory not present. "
+                                       "Dedicated debug bus.");
+
+               /* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */
+               entry_offset = 0;
+               do
+               {
+                       mem_ap_read_atomic_u32(swjdp, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
+                       command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%" PRIx32 "",entry_offset,romentry);
+                       if (romentry&0x01)
+                       {
+                               uint32_t c_cid0, c_cid1, c_cid2, c_cid3;
+                               uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4;
+                               uint32_t component_start, component_base;
+                               unsigned part_num;
+                               char *type, *full;
+
+                               component_base = (uint32_t)((dbgbase & 0xFFFFF000)
+                                               + (int)(romentry & 0xFFFFF000));
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFE0, &c_pid0);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFE4, &c_pid1);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFE8, &c_pid2);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFEC, &c_pid3);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFD0, &c_pid4);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFF0, &c_cid0);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFF4, &c_cid1);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFF8, &c_cid2);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFFC, &c_cid3);
+                               component_start = component_base - 0x1000*(c_pid4 >> 4);
+
+                               command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32
+                                               ", start address 0x%" PRIx32,
+                                               component_base, component_start);
+                               command_print(cmd_ctx, "\t\tComponent class is 0x%x, %s",
+                                               (int) (c_cid1 >> 4) & 0xf,
+                                               /* See ARM IHI 0029B Table 3-3 */
+                                               class_description[(c_cid1 >> 4) & 0xf]);
+
+                               /* CoreSight component? */
+                               if (((c_cid1 >> 4) & 0x0f) == 9) {
+                                       uint32_t devtype;
+                                       unsigned minor;
+                                       char *major = "Reserved", *subtype = "Reserved";
+
+                                       mem_ap_read_atomic_u32(swjdp,
+                                                       (component_base & 0xfffff000) | 0xfcc,
+                                                       &devtype);
+                                       minor = (devtype >> 4) & 0x0f;
+                                       switch (devtype & 0x0f) {
+                                       case 0:
+                                               major = "Miscellaneous";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 4:
+                                                       subtype = "Validation component";
+                                                       break;
+                                               }
+                                               break;
+                                       case 1:
+                                               major = "Trace Sink";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Port";
+                                                       break;
+                                               case 2:
+                                                       subtype = "Buffer";
+                                                       break;
+                                               }
+                                               break;
+                                       case 2:
+                                               major = "Trace Link";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Funnel, router";
+                                                       break;
+                                               case 2:
+                                                       subtype = "Filter";
+                                                       break;
+                                               case 3:
+                                                       subtype = "FIFO, buffer";
+                                                       break;
+                                               }
+                                               break;
+                                       case 3:
+                                               major = "Trace Source";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Processor";
+                                                       break;
+                                               case 2:
+                                                       subtype = "DSP";
+                                                       break;
+                                               case 3:
+                                                       subtype = "Engine/Coprocessor";
+                                                       break;
+                                               case 4:
+                                                       subtype = "Bus";
+                                                       break;
+                                               }
+                                               break;
+                                       case 4:
+                                               major = "Debug Control";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Trigger Matrix";
+                                                       break;
+                                               case 2:
+                                                       subtype = "Debug Auth";
+                                                       break;
+                                               }
+                                               break;
+                                       case 5:
+                                               major = "Debug Logic";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Processor";
+                                                       break;
+                                               case 2:
+                                                       subtype = "DSP";
+                                                       break;
+                                               case 3:
+                                                       subtype = "Engine/Coprocessor";
+                                                       break;
+                                               }
+                                               break;
+                                       }
+                                       command_print(cmd_ctx, "\t\tType is 0x%2.2x, %s, %s",
+                                                       (unsigned) (devtype & 0xff),
+                                                       major, subtype);
+                                       /* REVISIT also show 0xfc8 DevId */
+                               }
+
+                               if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
+                                       command_print(cmd_ctx, "\t\tCID3 0x%2.2" PRIx32
+                                                       ", CID2 0x%2.2" PRIx32
+                                                       ", CID1 0x%2.2" PRIx32
+                                                       ", CID0 0x%2.2" PRIx32,
+                                                       c_cid3, c_cid2, c_cid1, c_cid0);
+                               command_print(cmd_ctx, "\t\tPeripheral ID[4..0] = hex "
+                                               "%2.2x %2.2x %2.2x %2.2x %2.2x",
+                                               (int) c_pid4,
+                                               (int) c_pid3, (int) c_pid2,
+                                               (int) c_pid1, (int) c_pid0);
+
+                               /* Part number interpretations are from Cortex
+                                * core specs, the CoreSight components TRM
+                                * (ARM DDI 0314H), and ETM specs; also from
+                                * chip observation (e.g. TI SDTI).
+                                */
+                               part_num = c_pid0 & 0xff;
+                               part_num |= (c_pid1 & 0x0f) << 8;
+                               switch (part_num) {
+                               case 0x000:
+                                       type = "Cortex-M3 NVIC";
+                                       full = "(Interrupt Controller)";
+                                       break;
+                               case 0x001:
+                                       type = "Cortex-M3 ITM";
+                                       full = "(Instrumentation Trace Module)";
+                                       break;
+                               case 0x002:
+                                       type = "Cortex-M3 DWT";
+                                       full = "(Data Watchpoint and Trace)";
+                                       break;
+                               case 0x003:
+                                       type = "Cortex-M3 FBP";
+                                       full = "(Flash Patch and Breakpoint)";
+                                       break;
+                               case 0x00d:
+                                       type = "CoreSight ETM11";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               // case 0x113: what?
+                               case 0x120:             /* from OMAP3 memmap */
+                                       type = "TI SDTI";
+                                       full = "(System Debug Trace Interface)";
+                                       break;
+                               case 0x343:             /* from OMAP3 memmap */
+                                       type = "TI DAPCTL";
+                                       full = "";
+                                       break;
+                               case 0x906:
+                                       type = "Coresight CTI";
+                                       full = "(Cross Trigger)";
+                                       break;
+                               case 0x907:
+                                       type = "Coresight ETB";
+                                       full = "(Trace Buffer)";
+                                       break;
+                               case 0x908:
+                                       type = "Coresight CSTF";
+                                       full = "(Trace Funnel)";
+                                       break;
+                               case 0x910:
+                                       type = "CoreSight ETM9";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               case 0x912:
+                                       type = "Coresight TPIU";
+                                       full = "(Trace Port Interface Unit)";
+                                       break;
+                               case 0x921:
+                                       type = "Cortex-A8 ETM";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               case 0x922:
+                                       type = "Cortex-A8 CTI";
+                                       full = "(Cross Trigger)";
+                                       break;
+                               case 0x923:
+                                       type = "Cortex-M3 TPIU";
+                                       full = "(Trace Port Interface Unit)";
+                                       break;
+                               case 0x924:
+                                       type = "Cortex-M3 ETM";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               case 0xc08:
+                                       type = "Cortex-A8 Debug";
+                                       full = "(Debug Unit)";
+                                       break;
+                               default:
+                                       type = "-*- unrecognized -*-";
+                                       full = "";
+                                       break;
+                               }
+                               command_print(cmd_ctx, "\t\tPart is %s %s",
+                                               type, full);
+                       }
+                       else
+                       {
+                               if (romentry)
+                                       command_print(cmd_ctx, "\t\tComponent not present");
+                               else
+                                       command_print(cmd_ctx, "\t\tEnd of ROM table");
+                       }
+                       entry_offset += 4;
+               } while (romentry > 0);
+       }
+       else
+       {
+               command_print(cmd_ctx, "\tNo ROM table present");
+       }
+       dap_ap_select(swjdp, apselold);
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(handle_dap_info_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+       uint32_t apsel;
+
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = dap->apsel;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       return dap_info_command(CMD_CTX, dap, apsel);
+}
+
+COMMAND_HANDLER(dap_baseaddr_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+
+       uint32_t apsel, apselsave, baseaddr;
+       int retval;
+
+       apselsave = dap->apsel;
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = dap->apsel;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               /* AP address is in bits 31:24 of DP_SELECT */
+               if (apsel >= 256)
+                       return ERROR_INVALID_ARGUMENTS;
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       if (apselsave != apsel)
+               dap_ap_select(dap, apsel);
+
+       /* NOTE:  assumes we're talking to a MEM-AP, which
+        * has a base address.  There are other kinds of AP,
+        * though they're not common for now.  This should
+        * use the ID register to verify it's a MEM-AP.
+        */
+       retval = dap_queue_ap_read(dap, AP_REG_BASE, &baseaddr);
+       retval = dap_run(dap);
+       if (retval != ERROR_OK)
+               return retval;
+
+       command_print(CMD_CTX, "0x%8.8" PRIx32, baseaddr);
+
+       if (apselsave != apsel)
+               dap_ap_select(dap, apselsave);
+
+       return retval;
+}
+
+COMMAND_HANDLER(dap_memaccess_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+
+       uint32_t memaccess_tck;
+
+       switch (CMD_ARGC) {
+       case 0:
+               memaccess_tck = dap->memaccess_tck;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck);
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+       dap->memaccess_tck = memaccess_tck;
+
+       command_print(CMD_CTX, "memory bus access delay set to %" PRIi32 " tck",
+                       dap->memaccess_tck);
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(dap_apsel_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+
+       uint32_t apsel, apid;
+       int retval;
+
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = 0;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               /* AP address is in bits 31:24 of DP_SELECT */
+               if (apsel >= 256)
+                       return ERROR_INVALID_ARGUMENTS;
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       dap_ap_select(dap, apsel);
+       retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid);
+       retval = dap_run(dap);
+       if (retval != ERROR_OK)
+               return retval;
+
+       command_print(CMD_CTX, "ap %" PRIi32 " selected, identification register 0x%8.8" PRIx32,
+                       apsel, apid);
+
+       return retval;
+}
+
+COMMAND_HANDLER(dap_apid_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+
+       uint32_t apsel, apselsave, apid;
+       int retval;
+
+       apselsave = dap->apsel;
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = dap->apsel;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               /* AP address is in bits 31:24 of DP_SELECT */
+               if (apsel >= 256)
+                       return ERROR_INVALID_ARGUMENTS;
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       if (apselsave != apsel)
+               dap_ap_select(dap, apsel);
+
+       retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid);
+       retval = dap_run(dap);
+       if (retval != ERROR_OK)
+               return retval;
+
+       command_print(CMD_CTX, "0x%8.8" PRIx32, apid);
+       if (apselsave != apsel)
+               dap_ap_select(dap, apselsave);
+
+       return retval;
+}
+
+static const struct command_registration dap_commands[] = {
+       {
+               .name = "info",
+               .handler = handle_dap_info_command,
+               .mode = COMMAND_EXEC,
+               .help = "display ROM table for MEM-AP "
+                       "(default currently selected AP)",
+               .usage = "[ap_num]",
+       },
+       {
+               .name = "apsel",
+               .handler = dap_apsel_command,
+               .mode = COMMAND_EXEC,
+               .help = "Set the currently selected AP (default 0) "
+                       "and display the result",
+               .usage = "[ap_num]",
+       },
+       {
+               .name = "apid",
+               .handler = dap_apid_command,
+               .mode = COMMAND_EXEC,
+               .help = "return ID register from AP "
+                       "(default currently selected AP)",
+               .usage = "[ap_num]",
+       },
+       {
+               .name = "baseaddr",
+               .handler = dap_baseaddr_command,
+               .mode = COMMAND_EXEC,
+               .help = "return debug base address from MEM-AP "
+                       "(default currently selected AP)",
+               .usage = "[ap_num]",
+       },
+       {
+               .name = "memaccess",
+               .handler = dap_memaccess_command,
+               .mode = COMMAND_EXEC,
+               .help = "set/get number of extra tck for MEM-AP memory "
+                       "bus access [0-255]",
+               .usage = "[cycles]",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+const struct command_registration dap_command_handlers[] = {
+       {
+               .name = "dap",
+               .mode = COMMAND_EXEC,
+               .help = "DAP command group",
+               .chain = dap_commands,
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+
+/*
+ * This represents the bits which must be sent out on TMS/SWDIO to
+ * switch a DAP implemented using an SWJ-DP module into SWD mode.
+ * These bits are stored (and transmitted) LSB-first.
+ *
+ * See the DAP-Lite specification, section 2.2.5 for information
+ * about making the debug link select SWD or JTAG.  (Similar info
+ * is in a few other ARM documents.)
+ */
+static const uint8_t jtag2swd_bitseq[] = {
+       /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
+        * putting both JTAG and SWD logic into reset state.
+        */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* Switching sequence enables SWD and disables JTAG
+        * NOTE: bits in the DP's IDCODE may expose the need for
+        * an old/deprecated sequence (0xb6 0xed).
+        */
+       0x9e, 0xe7,
+       /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
+        * putting both JTAG and SWD logic into reset state.
+        */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+/**
+ * Put the debug link into SWD mode, if the target supports it.
+ * The link's initial mode may be either JTAG (for example,
+ * with SWJ-DP after reset) or SWD.
+ *
+ * @param target Enters SWD mode (if possible).
+ *
+ * Note that targets using the JTAG-DP do not support SWD, and that
+ * some targets which could otherwise support it may have have been
+ * configured to disable SWD signaling
+ *
+ * @return ERROR_OK or else a fault code.
+ */
+int dap_to_swd(struct target *target)
+{
+       int retval;
+
+       LOG_DEBUG("Enter SWD mode");
+
+       /* REVISIT it's nasty to need to make calls to a "jtag"
+        * subsystem if the link isn't in JTAG mode...
+        */
+
+       retval =  jtag_add_tms_seq(8 * sizeof(jtag2swd_bitseq),
+                       jtag2swd_bitseq, TAP_INVALID);
+       if (retval == ERROR_OK)
+               retval = jtag_execute_queue();
+
+       /* REVISIT set up the DAP's ops vector for SWD mode. */
+
+       return retval;
+}
+
index 720261eea48cccbf560d770df05d4827a92c4875..17f7c241e67308950b49da745d42878b71fb9ee1 100644 (file)
@@ -190,8 +190,7 @@ int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_l
        }
 
        {
-               jtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in,
-                               jtag_set_end_state(TAP_IDLE));
+               jtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in, TAP_IDLE);
        }
 
        return ERROR_OK;
@@ -206,7 +205,7 @@ int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, int dr_l
        }
 
        {
-               jtag_add_plain_dr_scan(dr_len, dr_out, dr_in, jtag_set_end_state(TAP_IDLE));
+               jtag_add_plain_dr_scan(dr_len, dr_out, dr_in, TAP_IDLE);
        }
 
        return ERROR_OK;
index 4be7f3b5ed9c4f2f275c29d92629e23d48a9585b..b42e7b3ece698a87ddf57bb1f29d694cae49907c 100644 (file)
@@ -863,8 +863,7 @@ int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t * ir_in, uint8_t * ir_out,
        }
 
        {
-               jtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in,
-                                      jtag_set_end_state(TAP_IDLE));
+               jtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in, TAP_IDLE);
        }
 
        return ERROR_OK;
@@ -880,8 +879,7 @@ int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t * dr_in, uint8_t * dr_out,
        }
 
        {
-               jtag_add_plain_dr_scan(dr_len, dr_out, dr_in,
-                                      jtag_set_end_state(TAP_IDLE));
+               jtag_add_plain_dr_scan(dr_len, dr_out, dr_in, TAP_IDLE);
        }
 
        return ERROR_OK;
index 4693fcc2274390e900b1103ea45882ebd43f345e..fe266d62814696324bc6c7e64402aab3dd7953c3 100644 (file)
@@ -372,7 +372,7 @@ int embeddedice_read_reg_w_check(struct reg *reg,
        fields[2].check_mask = NULL;
 
        /* traverse Update-DR, setting address for the next read */
-       jtag_add_dr_scan(ice_reg->jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(ice_reg->jtag_info->tap, 3, fields, TAP_IDLE);
 
        /* bits 31:0 -- the data we're reading (and maybe checking) */
        fields[0].in_value = reg->value;
@@ -386,7 +386,7 @@ int embeddedice_read_reg_w_check(struct reg *reg,
        fields[1].out_value[0] = eice_regs[EICE_COMMS_CTRL].addr;
 
        /* traverse Update-DR, reading but with no other side effects */
-       jtag_add_dr_scan_check(ice_reg->jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan_check(ice_reg->jtag_info->tap, 3, fields, TAP_IDLE);
 
        return ERROR_OK;
 }
@@ -423,7 +423,7 @@ int embeddedice_receive(struct arm_jtag *jtag_info, uint32_t *data, uint32_t siz
        fields[2].out_value[0] = 0;
        fields[2].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
 
        while (size > 0)
        {
@@ -434,7 +434,7 @@ int embeddedice_receive(struct arm_jtag *jtag_info, uint32_t *data, uint32_t siz
                        fields[1].out_value[0] = eice_regs[EICE_COMMS_CTRL].addr;
 
                fields[0].in_value = (uint8_t *)data;
-               jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+               jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
                jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)data);
 
                data++;
@@ -545,7 +545,7 @@ int embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size)
        while (size > 0)
        {
                buf_set_u32(fields[0].out_value, 0, 32, *data);
-               jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+               jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
 
                data++;
                size--;
@@ -594,10 +594,10 @@ int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeou
        fields[2].out_value[0] = 0;
        fields[2].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
        gettimeofday(&lap, NULL);
        do {
-               jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+               jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
                if ((retval = jtag_execute_queue()) != ERROR_OK)
                        return retval;
 
index 2c4e3ebe90037e5c4330857fd3a34677057a6895..99710700ec4eaabbe924f3a0bb7e2bd3541fb25a 100644 (file)
@@ -191,7 +191,7 @@ static int etb_read_ram(struct etb *etb, uint32_t *data, int num_frames)
        buf_set_u32(fields[2].out_value, 0, 1, 0);
        fields[2].in_value = NULL;
 
-       jtag_add_dr_scan(etb->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(etb->tap, 3, fields, TAP_IDLE);
 
        for (i = 0; i < num_frames; i++)
        {
@@ -205,7 +205,7 @@ static int etb_read_ram(struct etb *etb, uint32_t *data, int num_frames)
                        buf_set_u32(fields[1].out_value, 0, 7, 0);
 
                fields[0].in_value = (uint8_t *)(data + i);
-               jtag_add_dr_scan(etb->tap, 3, fields, jtag_get_end_state());
+               jtag_add_dr_scan(etb->tap, 3, fields, TAP_IDLE);
 
                jtag_add_callback(etb_getbuf, (jtag_callback_data_t)(data + i));
        }
@@ -251,7 +251,7 @@ static int etb_read_reg_w_check(struct reg *reg,
        fields[2].check_value = NULL;
        fields[2].check_mask = NULL;
 
-       jtag_add_dr_scan(etb_reg->etb->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(etb_reg->etb->tap, 3, fields, TAP_IDLE);
 
        /* read the identification register in the second run, to make sure we
         * don't read the ETB data register twice, skipping every second entry
@@ -261,7 +261,7 @@ static int etb_read_reg_w_check(struct reg *reg,
        fields[0].check_value = check_value;
        fields[0].check_mask = check_mask;
 
-       jtag_add_dr_scan_check(etb_reg->etb->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan_check(etb_reg->etb->tap, 3, fields, TAP_IDLE);
 
        free(fields[1].out_value);
        free(fields[2].out_value);
index 67dac06fadabb51ed5c16ee102fc113c3700908d..a1c77b0ff3392e77de20a5917eb09dcb48793c64 100644 (file)
@@ -528,13 +528,13 @@ static int etm_read_reg_w_check(struct reg *reg,
        fields[2].check_value = NULL;
        fields[2].check_mask = NULL;
 
-       jtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE);
 
        fields[0].in_value = reg->value;
        fields[0].check_value = check_value;
        fields[0].check_mask = check_mask;
 
-       jtag_add_dr_scan_check(etm_reg->jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan_check(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE);
 
        free(fields[1].out_value);
        free(fields[2].out_value);
@@ -609,7 +609,7 @@ static int etm_write_reg(struct reg *reg, uint32_t value)
        buf_set_u32(fields[2].out_value, 0, 1, 1);
        fields[2].in_value = NULL;
 
-       jtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE);
 
        return ERROR_OK;
 }
index 133ad4f66ce9b55a498128dca8ab908e1b460738..22ddb5573e9d77fed67dac5a1815bff520339500 100644 (file)
@@ -101,9 +101,9 @@ int feroceon_dummy_clock_out(struct arm_jtag *jtag_info, uint32_t instr)
        fields[2].out_value = instr_buf;
        fields[2].in_value = NULL;
 
-       jtag_add_dr_scan(jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);
 
-       /* no jtag_add_runtest(0, jtag_get_end_state()) here */
+       /* no jtag_add_runtest(0, TAP_DRPAUSE) here */
 
        return ERROR_OK;
 }
index 42dc6e0b54011f6be0f455f8554c2c3dc2252a50..974c836dce35d1181ecb05ceedf124f30140901a 100644 (file)
@@ -64,7 +64,7 @@ int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info, uint32_t *idcode)
        field.out_value = NULL;
        field.in_value = (void*)idcode;
 
-       jtag_add_dr_scan(ejtag_info->tap, 1, &field, jtag_get_end_state());
+       jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE);
 
        if (jtag_execute_queue() != ERROR_OK)
        {
@@ -86,7 +86,7 @@ int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info, uint32_t *impcode)
        field.out_value = NULL;
        field.in_value = (void*)impcode;
 
-       jtag_add_dr_scan(ejtag_info->tap, 1, &field, jtag_get_end_state());
+       jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE);
 
        if (jtag_execute_queue() != ERROR_OK)
        {
index dd4a7ee622da8c18dd3206c0542f263262d5e496..f5aada507d54557826091ab95ff865f4ef228b33 100644 (file)
@@ -213,7 +213,7 @@ static int xscale_read_dcsr(struct target *target)
        uint8_t tmp2;
        fields[2].in_value = &tmp2;
 
-       jtag_add_dr_scan(target->tap, 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,7 +236,7 @@ static int xscale_read_dcsr(struct target *target)
 
        jtag_set_end_state(TAP_IDLE);
 
-       jtag_add_dr_scan(target->tap, 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! */
@@ -288,7 +288,7 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
        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 */
+       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;
@@ -304,7 +304,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(target->tap, 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));
 
@@ -411,7 +411,7 @@ static int xscale_read_tx(struct target *target, int consume)
                        jtag_add_pathmove(ARRAY_SIZE(noconsume_path), noconsume_path);
                }
 
-               jtag_add_dr_scan(target->tap, 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);
@@ -489,7 +489,7 @@ static int xscale_write_rx(struct target *target)
        LOG_DEBUG("polling RX");
        for (;;)
        {
-               jtag_add_dr_scan(target->tap, 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);
@@ -521,7 +521,7 @@ static int xscale_write_rx(struct target *target)
 
        /* set rx_valid */
        field2 = 0x1;
-       jtag_add_dr_scan(target->tap, 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)
        {
@@ -585,7 +585,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;
        }
 
@@ -646,7 +646,7 @@ static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_br
        uint8_t tmp2;
        fields[2].in_value = &tmp2;
 
-       jtag_add_dr_scan(target->tap, 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);
@@ -707,7 +707,7 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
        fields[1].num_bits = 27;
        fields[1].out_value = packet;
 
-       jtag_add_dr_scan(target->tap, 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;
@@ -724,7 +724,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(target->tap, 2, fields, jtag_get_end_state());
+               jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);
        }
 
        return jtag_execute_queue();
@@ -755,7 +755,7 @@ static int xscale_invalidate_ic_line(struct target *target, uint32_t va)
        fields[1].num_bits = 27;
        fields[1].out_value = packet;
 
-       jtag_add_dr_scan(target->tap, 2, fields, jtag_get_end_state());
+       jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);
 
        return ERROR_OK;
 }
@@ -1556,7 +1556,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 */
@@ -1613,7 +1613,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);
 
index f2c1a4220a2a0eec8aa2110a7d0f5a50e09fbdef..dff1a1ec2ab0c862246ce913e880fce660b5835c 100644 (file)
@@ -482,9 +482,9 @@ COMMAND_HANDLER(handle_xsvf_command)
 
                                        if (tap == NULL)
                                                jtag_add_plain_dr_scan(field.num_bits, field.out_value, field.in_value,
-                                                               jtag_set_end_state(TAP_DRPAUSE));
+                                                               TAP_DRPAUSE);
                                        else
-                                               jtag_add_dr_scan(tap, 1, &field, jtag_set_end_state(TAP_DRPAUSE));
+                                               jtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE);
 
                                        jtag_check_value_mask(&field, dr_in_buf, dr_in_mask);
 
@@ -939,9 +939,9 @@ COMMAND_HANDLER(handle_xsvf_command)
 
                                        if (tap == NULL)
                                                jtag_add_plain_dr_scan(field.num_bits, field.out_value, field.in_value,
-                                                               jtag_set_end_state(TAP_DRPAUSE));
+                                                               TAP_DRPAUSE);
                                        else
-                                               jtag_add_dr_scan(tap, 1, &field, jtag_set_end_state(TAP_DRPAUSE));
+                                               jtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE);
 
                                        jtag_check_value_mask(&field, dr_in_buf, dr_in_mask);
 

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)