]> git.sur5r.net Git - openocd/commitdiff
- added support for Intel/Marvel PXA27x (XScale) targets
authordrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 21 Jun 2007 13:15:22 +0000 (13:15 +0000)
committerdrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 21 Jun 2007 13:15:22 +0000 (13:15 +0000)
- added support for scans coming from or ending in Shift-DR or Shift-IR to bitbang code (required for XScale debugging)
- cleaned up errror handlers. only use when there's a catchable error
- fix segfault when etm was configured without a valid driver

git-svn-id: svn://svn.berlios.de/openocd/trunk@176 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/jtag/bitbang.c
src/jtag/jtag.c
src/jtag/jtag.h
src/target/arm7_9_common.c
src/target/arm9tdmi.c
src/target/cortex_swjdp.c
src/target/embeddedice.c
src/target/etm.c
src/target/xscale.c

index 82e92a2100ce423d58a51d29ee3ded01520d344f..198a741fd78ce66b98f0d2965f62d976483227ca 100644 (file)
@@ -132,21 +132,35 @@ void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
        enum tap_state saved_end_state = end_state;
        int bit_cnt;
        
-       if (ir_scan)
-               bitbang_end_state(TAP_SI);
-       else
-               bitbang_end_state(TAP_SD);
+       if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI))))
+       {
+               if (ir_scan)
+                       bitbang_end_state(TAP_SI);
+               else
+                       bitbang_end_state(TAP_SD);
 
-       bitbang_state_move();
-       bitbang_end_state(saved_end_state);
+               bitbang_state_move();
+               bitbang_end_state(saved_end_state);
+       }
 
        for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++)
        {
+               /* set TMS high on the last bit unless we want to end in TAP_SD/SI */
+               int tms;
+               if ((ir_scan && (end_state == TAP_SI)) ||
+                       (!ir_scan && (end_state == TAP_SD)))
+               {
+                       tms = 0;
+               } else {
+                       tms = (bit_cnt==scan_size-1) ? 1 : 0;
+               }
+               
                /* if we're just reading the scan, but don't care about the output
                 * default to outputting 'low', this also makes valgrind traces more readable,
                 * as it removes the dependency on an uninitialised value
                 */ 
-               if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1)) {
+               if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1))
+               {
                        bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 1);
                        bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 1);
                } else {
index 6dfde760112f3b9fc66b9d472319949e0d5236f7..9891912347577ea8c5a753c117681ba70003eab6 100644 (file)
@@ -58,6 +58,8 @@ static cmd_queue_page_t *cmd_queue_pages = NULL;
  * 3: Pause-DR
  * 4: Shift-IR
  * 5: Pause-IR
+ * 
+ * SD->SD and SI->SI have to be caught in interface specific code
  */
 u8 tap_move[6][6] =
 {
@@ -1086,9 +1088,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
                                
                                if (compare_failed)
                                {
-                                       char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
-                                       char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, (num_bits > 64) ? 64 : num_bits, 16);
-
                                        if (cmd->error_handler)
                                        {
                                                /* ask the error handler if once has been specified if this is a real problem */ 
@@ -1109,6 +1108,9 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
                                         */ 
                                        if (compare_failed)
                                        {
+                                               char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
+                                               char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, (num_bits > 64) ? 64 : num_bits, 16);
+
                                                if (cmd->fields[i].in_check_mask)
                                                {
                                                        char *in_check_mask_char;
@@ -1120,10 +1122,11 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
                                                {
                                                        WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s", captured_char, in_check_value_char);
                                                }
+
+                                               free(captured_char);
+                                               free(in_check_value_char);
                                        }
                                        
-                                       free(captured_char);
-                                       free(in_check_value_char);
                                }
                        }
                        free(captured);
index 1464a080bc262cb6230f72f60903b841c69c1a41..1b03d615b9625d488e18a991e8177cd315977d18 100644 (file)
@@ -59,6 +59,9 @@ extern tap_transition_t tap_transitions[16];  /* describe the TAP state diagram *
 extern enum tap_state end_state;               /* finish DR scans in dr_end_state */
 extern enum tap_state cur_state;               /* current TAP state */
 
+extern enum tap_state cmd_queue_end_state;             /* finish DR scans in dr_end_state */
+extern enum tap_state cmd_queue_cur_state;             /* current TAP state */
+
 #define TAP_MOVE(from, to) tap_move[tap_move_map[from]][tap_move_map[to]]
 
 typedef struct error_handler_s
index 77a43feebb265a845b4a8e423da7f5079e2908e4..cda99d842a05126ca9ec9cd8cedef4cb15e13b9c 100644 (file)
@@ -846,6 +846,13 @@ int arm7_9_prepare_reset_halt(target_t *target)
        armv4_5_common_t *armv4_5 = target->arch_info;
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
        
+       /* poll the target, and resume if it was currently halted */
+       arm7_9_poll(target);
+       if (target->state == TARGET_HALTED)
+       {
+               arm7_9_resume(target, 1, 0x0, 0, 1);
+       }
+       
        if (arm7_9->has_vector_catch)
        {
                /* program vector catch register to catch reset vector */
index 7ecd1f0d58463a638578cd5ed0a182e1d9b8d23c..3b06b0e48d50155fca4588e86a8eef7ecf062b28 100644 (file)
@@ -104,7 +104,7 @@ int arm9tdmi_jtag_error_handler(u8 *in_value, void *priv)
        
        DEBUG("caller: %s", caller);
        
-       return ERROR_OK;
+       return ERROR_JTAG_QUEUE_FAILED;
 }
 
 int arm9tdmi_examine_debug_reason(target_t *target)
@@ -117,7 +117,6 @@ int arm9tdmi_examine_debug_reason(target_t *target)
        if ((target->debug_reason != DBG_REASON_DBGRQ)
                        && (target->debug_reason != DBG_REASON_SINGLESTEP))
        {
-               error_handler_t error_handler;
                scan_field_t fields[3];
                u8 databus[4];
                u8 instructionbus[4];
@@ -156,9 +155,7 @@ int arm9tdmi_examine_debug_reason(target_t *target)
                fields[2].in_handler_priv = NULL;
                
                arm_jtag_scann(&arm7_9->jtag_info, 0x1);
-               error_handler.error_handler = arm9tdmi_jtag_error_handler;
-               error_handler.error_handler_priv = "arm9tdmi_examine_debug_reason";
-               arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, &error_handler);
+               arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
 
                jtag_add_dr_scan(3, fields, TAP_PD, NULL);
                jtag_execute_queue();
@@ -187,7 +184,6 @@ int arm9tdmi_examine_debug_reason(target_t *target)
 /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
 int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed)
 {
-       error_handler_t error_handler;
        scan_field_t fields[3];
        u8 out_buf[4];
        u8 instr_buf[4];
@@ -204,10 +200,7 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
        jtag_add_end_state(TAP_PD);
        arm_jtag_scann(jtag_info, 0x1);
        
-       error_handler.error_handler = arm9tdmi_jtag_error_handler;
-       error_handler.error_handler_priv = "arm9tdmi_clock_out";
-       
-       arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler);
+       arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
                
        fields[0].device = jtag_info->chain_pos;
        fields[0].num_bits = 32;
@@ -271,15 +264,11 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
 int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
 {
        scan_field_t fields[3];
-       error_handler_t error_handler;
 
        jtag_add_end_state(TAP_PD);
        arm_jtag_scann(jtag_info, 0x1);
        
-       error_handler.error_handler = arm9tdmi_jtag_error_handler;
-       error_handler.error_handler_priv = "arm9tdmi_clock_data_in_endianness";
-       
-       arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler);
+       arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
                
        fields[0].device = jtag_info->chain_pos;
        fields[0].num_bits = 32;
@@ -340,15 +329,11 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
 int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
 {
        scan_field_t fields[3];
-       error_handler_t error_handler;
        
        jtag_add_end_state(TAP_PD);
        arm_jtag_scann(jtag_info, 0x1);
        
-       error_handler.error_handler = arm9tdmi_jtag_error_handler;
-       error_handler.error_handler_priv = "arm9tdmi_clock_data_in_endianness";
-       
-       arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler);
+       arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
                
        fields[0].device = jtag_info->chain_pos;
        fields[0].num_bits = 32;
index 15fc26da5eb9b2579e9435941dd3bd9eeed9701c..e50c684374c2cb87f26a3f9377b5a2d516a516cf 100644 (file)
@@ -54,26 +54,14 @@ are immediatley available.
  *                                                                         *
 ***************************************************************************/
 
-int swjdp_jtag_error_handler(u8 *in_value, void *priv)
-{
-       char *caller = priv;
-       
-       DEBUG("caller: %s", caller);
-       
-       return ERROR_OK;
-}
-
 /* Scan out and in from target ordered u8 buffers */
 int swjdp_scan(arm_jtag_t *jtag_info, u8 chain, u8 reg_addr, u8 RnW, u8 *outvalue, u8 *invalue, u8 *ack)
 {
        scan_field_t fields[2];
        u8 out_addr_buf;
-       error_handler_t error_handler;
        
        jtag_add_end_state(TAP_RTI);
-       error_handler.error_handler = swjdp_jtag_error_handler;
-       error_handler.error_handler_priv = "swjdp_scan";
-       arm_jtag_set_instr(jtag_info, chain, &error_handler);
+       arm_jtag_set_instr(jtag_info, chain, NULL);
 
        fields[0].device = jtag_info->chain_pos;
        fields[0].num_bits = 3;
@@ -108,12 +96,9 @@ int swjdp_scan_u32(arm_jtag_t *jtag_info, u8 chain, u8 reg_addr, u8 RnW, u32 out
        scan_field_t fields[2];
        u8 out_value_buf[4];
        u8 out_addr_buf;
-       error_handler_t error_handler;
        
        jtag_add_end_state(TAP_RTI);
-       error_handler.error_handler = swjdp_jtag_error_handler;
-       error_handler.error_handler_priv = "swjdp_scan_u32";
-       arm_jtag_set_instr(jtag_info, chain, &error_handler);
+       arm_jtag_set_instr(jtag_info, chain, NULL);
 
        fields[0].device = jtag_info->chain_pos;
        fields[0].num_bits = 3;
index ef38e13694a8a5f22a94be995aee664cf3dfa6ff..f601c1ebbbaac89bfd6896e0d4d875cbc75e53f4 100644 (file)
@@ -86,15 +86,6 @@ int embeddedice_set_reg_w_exec(reg_t *reg, u8 *buf);
 int embeddedice_write_reg(reg_t *reg, u32 value);
 int embeddedice_read_reg(reg_t *reg);
 
-int embeddedice_jtag_error_handler(u8 *in_value, void *priv)
-{
-       char *caller = priv;
-       
-       DEBUG("caller: %s", caller);
-       
-       return ERROR_OK;
-}
-
 reg_cache_t* embeddedice_build_reg_cache(target_t *target, arm7_9_common_t *arm7_9)
 {
        reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
@@ -223,17 +214,13 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
        embeddedice_reg_t *ice_reg = reg->arch_info;
        u8 reg_addr = ice_reg->addr & 0x1f;
        scan_field_t fields[3];
-       error_handler_t error_handler;
        
        DEBUG("%i", ice_reg->addr);
 
        jtag_add_end_state(TAP_RTI);
        arm_jtag_scann(ice_reg->jtag_info, 0x2);
        
-       error_handler.error_handler = embeddedice_jtag_error_handler;
-       error_handler.error_handler_priv = "embeddedice_read_reg_w_check";
-       
-       arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, &error_handler);
+       arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, NULL);
        
        fields[0].device = ice_reg->jtag_info->chain_pos;
        fields[0].num_bits = 32;
@@ -324,16 +311,12 @@ int embeddedice_write_reg(reg_t *reg, u32 value)
        embeddedice_reg_t *ice_reg = reg->arch_info;
        u8 reg_addr = ice_reg->addr & 0x1f;
        scan_field_t fields[3];
-       error_handler_t error_handler;
        
        DEBUG("%i: 0x%8.8x", ice_reg->addr, value);
        
        jtag_add_end_state(TAP_RTI);
        arm_jtag_scann(ice_reg->jtag_info, 0x2);
        
-       error_handler.error_handler = embeddedice_jtag_error_handler;
-       error_handler.error_handler_priv = "embeddedice_write_reg";
-       
        arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, NULL);
        
        fields[0].device = ice_reg->jtag_info->chain_pos;
index dd6e6025d2f9075dc27568d39f443da34026cf79..b4c20750bced8903759d83da31f42762996fa8ea 100644 (file)
@@ -1231,6 +1231,14 @@ int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cmd, char
                }
        }
        
+       if (!etm_capture_drivers[i])
+       {
+               /* no supported capture driver found, don't register an ETM */
+               free(etm_ctx);
+               ERROR("trace capture driver '%s' not found", args[4]);
+               return ERROR_OK;
+       }
+       
        etm_ctx->target = target;
        etm_ctx->trace_data = NULL;
        etm_ctx->trace_depth = 0;
index 311e53bc98d99c9f610a4275db83b98a8c3416b7..2cfc23e71d2f73bf0d0026a446df0a0fabe844af 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2006 by Dominic Rath                                    *
+ *   Copyright (C) 2006, 2007 by Dominic Rath                              *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 #include "binarybuffer.h"
 #include "time_support.h"
 #include "breakpoints.h"
+#include "fileio.h"
 
 #include <stdlib.h>
 #include <string.h>
 
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <unistd.h>
 #include <errno.h>
 
+
 /* cli handling */
 int xscale_register_commands(struct command_context_s *cmd_ctx);
 
@@ -1197,9 +1198,6 @@ int xscale_halt(target_t *target)
        else if (target->state == TARGET_RESET)
        {
                DEBUG("target->state == TARGET_RESET");
-               
-               /* clear TRST */
-               jtag_add_reset(0, -1);
        }
        else
        {
@@ -1517,22 +1515,32 @@ int xscale_assert_reset(target_t *target)
        xscale_common_t *xscale = armv4_5->arch_info;
        
        DEBUG("target->state: %s", target_state_strings[target->state]);
+
+       /* select DCSR instruction (set endstate to R-T-I to ensure we don't 
+        * end up in T-L-R, which would reset JTAG
+        */ 
+       jtag_add_end_state(TAP_RTI);
+       xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dcsr);
        
-       /* if the handler isn't installed yet, we have to assert TRST, too */
-       if (!xscale->handler_installed)
-       {
-               jtag_add_reset(1, 1);
-       }
-       else
-               jtag_add_reset(-1, 1);
+       /* set Hold reset, Halt mode and Trap Reset */
+       buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
+       buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
+       xscale_write_dcsr(target, 1, 0);
+
+       /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
+       xscale_jtag_set_instr(xscale->jtag_info.chain_pos, 0x7f);
+       jtag_execute_queue();
+               
+       /* assert reset */      
+       jtag_add_reset(0, 1);
        
        /* sleep 1ms, to be sure we fulfill any requirements */
        jtag_add_sleep(1000);
+       jtag_execute_queue();
        
        target->state = TARGET_RESET;
        
        return ERROR_OK;
-
 }
 
 int xscale_deassert_reset(target_t *target)
@@ -1540,17 +1548,18 @@ int xscale_deassert_reset(target_t *target)
        armv4_5_common_t *armv4_5 = target->arch_info;
        xscale_common_t *xscale = armv4_5->arch_info;
        
-       FILE *binary;
+       fileio_t debug_handler;
        u32 address;
-       struct stat binary_stat;
        u32 binary_size;
 
-       u32 buffer[8];
        u32 buf_cnt;
        int i;
+       int retval;
        
        breakpoint_t *breakpoint = target->breakpoints;
        
+       DEBUG("-");
+       
        xscale->ibcr_available = 2;
        xscale->ibcr0_used = 0;
        xscale->ibcr1_used = 0;
@@ -1571,42 +1580,27 @@ int xscale_deassert_reset(target_t *target)
        
        if (!xscale->handler_installed)
        {
-               /* release TRST */
-               jtag_add_reset(0, -1);
-               jtag_add_sleep(100000);
-               
-               /* set Hold reset, Halt mode and Trap Reset */
-               buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
-               buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
-               xscale_write_dcsr(target, 1, 0);
-               jtag_add_runtest(100, TAP_RTI);
-               jtag_execute_queue();
-               
                /* release SRST */
                jtag_add_reset(0, 0);
-               /* wait 150ms; 100ms were not enough */
-               jtag_add_sleep(150000);
+               
+               /* wait 300ms; 150 and 100ms were not enough */
+               jtag_add_sleep(3000000);
 
                jtag_add_runtest(2030, TAP_RTI);
                jtag_execute_queue();
-               
+
+               /* set Hold reset, Halt mode and Trap Reset */
+               buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
+               buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
                xscale_write_dcsr(target, 1, 0);
-               jtag_execute_queue();
-               
-               /* TODO: load debug handler */
-               if (stat("target/xscale/debug_handler.bin", &binary_stat) == -1)
-               {
-                       ERROR("couldn't stat() target/xscale/debug_handler.bin: %s",  strerror(errno));
-                       return ERROR_OK;
-               }
-               
-               if (!(binary = fopen("target/xscale/debug_handler.bin", "r")))
+
+               if (fileio_open(&debug_handler, "target/xscale/debug_handler.bin", FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
                {
-                       ERROR("couldn't open target/xscale/debug_handler.bin: %s", strerror(errno));
+                       ERROR("file open error: %s", debug_handler.error_str);
                        return ERROR_OK;
                }
-               
-               if ((binary_size = binary_stat.st_size) % 4)
+       
+               if ((binary_size = debug_handler.size) % 4)
                {
                        ERROR("debug_handler.bin: size not a multiple of 4");
                        exit(-1);
@@ -1623,41 +1617,51 @@ int xscale_deassert_reset(target_t *target)
                address = xscale->handler_address;
                while (binary_size > 0)
                {
-                       buf_cnt = fread(buffer, 4, 8, binary);
+                       u32 cache_line[8];
+                       u8 buffer[32];
+                       
+                       if ((retval = fileio_read(&debug_handler, 32, buffer, &buf_cnt)) != ERROR_OK)
+                       {
+                               ERROR("reading debug handler failed: %s", debug_handler.error_str);
+                       }
                        
-                       for (i = 0; i < buf_cnt; i++)
+                       for (i = 0; i < buf_cnt; i += 4)
                        {
                                /* convert LE buffer to host-endian u32 */
-                               buffer[i] = buf_get_u32((u8*)(&buffer[i]), 0, 32);
+                               cache_line[i / 4] = le_to_h_u32(&buffer[i]);
                        }
                        
-                       if (buf_cnt < 8)
+                       for (; buf_cnt < 32; buf_cnt += 4)
                        {
-                               for (; buf_cnt < 8; buf_cnt++)
-                               {
-                                       buffer[buf_cnt] = 0xe1a08008;
-                               }
+                                       cache_line[buf_cnt / 4] = 0xe1a08008;
                        }
                        
                        /* only load addresses other than the reset vectors */
                        if ((address % 0x400) != 0x0)
                        {
-                               xscale_load_ic(target, 1, address, buffer);
+                               xscale_load_ic(target, 1, address, cache_line);
                        }
                        
-                       address += buf_cnt * 4;
-                       binary_size -= buf_cnt * 4;
+                       address += buf_cnt;
+                       binary_size -= buf_cnt;
                };
                
                xscale_load_ic(target, 1, 0x0, xscale->low_vectors);
                xscale_load_ic(target, 1, 0xffff0000, xscale->high_vectors);
        
                jtag_add_runtest(30, TAP_RTI);
+
+               jtag_add_sleep(100000);
                
-               /* let the target run (should enter debug handler) */
-               xscale_write_dcsr(target, 0, 0);
+               /* set Hold reset, Halt mode and Trap Reset */
+               buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
+               buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
+               xscale_write_dcsr(target, 1, 0);
+
+               /* clear Hold reset to let the target run (should enter debug handler) */
+               xscale_write_dcsr(target, 0, 1);
                target->state = TARGET_RUNNING;
-               
+
                if ((target->reset_mode != RESET_HALT) && (target->reset_mode != RESET_INIT))
                {
                        jtag_add_sleep(10000);
@@ -1666,8 +1670,8 @@ int xscale_deassert_reset(target_t *target)
                        xscale_debug_entry(target);
                        target->state = TARGET_HALTED;
                        
-                       /* the PC is now at 0x0 */
-                       buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
+                       /* resume the target */
+                       xscale_resume(target, 1, 0x0, 1, 0);
                }
        }
        else
@@ -1687,7 +1691,9 @@ int xscale_soft_reset_halt(struct target_s *target)
 
 int xscale_prepare_reset_halt(struct target_s *target)
 {
-       /* nothing to be done for reset_halt on XScale targets */
+       /* nothing to be done for reset_halt on XScale targets
+        * we always halt after a reset to upload the debug handler
+        */
        return ERROR_OK;
 }
 
@@ -2584,6 +2590,10 @@ int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *targe
                ERROR("Reset target to enable debug");
        }
        
+       /* assert TRST once during startup */
+       jtag_add_reset(1, 0);
+       jtag_add_reset(0, 0);
+       
        return ERROR_OK;
 }