- jtag_khz/speed are now single parameter only. These are used
[fw/openocd] / src / target / arm7_9_common.c
index 9cf38c3e6dcf6bcd0379a8fae3f5abe2fb874e0f..563f470159682725ed59be87f5980a19c1e6d63a 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "embeddedice.h"
 #include "target.h"
+#include "target_request.h"
 #include "armv4_5.h"
 #include "arm_jtag.h"
 #include "jtag.h"
@@ -83,27 +84,17 @@ int arm7_9_reinit_embeddedice(target_t *target)
                arm7_9_enable_sw_bkpts(target);
        }
        
-       arm7_9->reinit_embeddedice = 0;
-       
        return ERROR_OK;
 }
 
-int arm7_9_jtag_callback(enum jtag_event event, void *priv)
+/* set things up after a reset / on startup */
+int arm7_9_setup(target_t *target)
 {
-       target_t *target = priv;
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       arm7_9_common_t *arm7_9 = armv4_5->arch_info;
-       
-       /* a test-logic reset occured
+       /* a test-logic reset have occured
         * the EmbeddedICE registers have been reset
         * hardware breakpoints have been cleared
         */
-       if (event == JTAG_TRST_ASSERTED)
-       {
-               arm7_9->reinit_embeddedice = 1;
-       }
-       
-       return ERROR_OK;
+       return arm7_9_reinit_embeddedice(target);
 }
 
 int arm7_9_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p)
@@ -134,7 +125,7 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
@@ -143,7 +134,7 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
 
        if (breakpoint->set)
        {
-               WARNING("breakpoint already set");
+               LOG_WARNING("breakpoint already set");
                return ERROR_OK;
        }
 
@@ -177,7 +168,7 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
                }
                else
                {
-                       ERROR("BUG: no hardware comparator available");
+                       LOG_ERROR("BUG: no hardware comparator available");
                        return ERROR_OK;
                }
        }
@@ -185,17 +176,33 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
        {
                if (breakpoint->length == 4)
                {
+                       u32 verify = 0xffffffff;
                        /* keep the original instruction in target endianness */
                        target->type->read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
-                       /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
+                       /* write the breakpoint instruction in target endianness (arm7_9->arm_bkpt is host endian) */
                        target_write_u32(target, breakpoint->address, arm7_9->arm_bkpt);
+                       
+                       target->type->read_memory(target, breakpoint->address, 4, 1, (u8 *)&verify);
+                       if (verify != arm7_9->arm_bkpt)
+                       {
+                               LOG_ERROR("Unable to set 32 bit software breakpoint at address %08x - check that memory is read/writable", breakpoint->address);
+                               return ERROR_OK;
+                       }
                }
                else
                {
+                       u16 verify = 0xffff;
                        /* keep the original instruction in target endianness */
                        target->type->read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
-                       /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
-                       target_write_u32(target, breakpoint->address, arm7_9->thumb_bkpt);
+                       /* write the breakpoint instruction in target endianness (arm7_9->thumb_bkpt is host endian) */
+                       target_write_u16(target, breakpoint->address, arm7_9->thumb_bkpt);
+                       
+                       target->type->read_memory(target, breakpoint->address, 2, 1, (u8 *)&verify);
+                       if (verify != arm7_9->thumb_bkpt)
+                       {
+                               LOG_ERROR("Unable to set thumb software breakpoint at address %08x - check that memory is read/writable", breakpoint->address);
+                               return ERROR_OK;
+                       }
                }
                breakpoint->set = 1;
        }
@@ -211,13 +218,13 @@ int arm7_9_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
        if (!breakpoint->set)
        {
-               WARNING("breakpoint not set");
+               LOG_WARNING("breakpoint not set");
                return ERROR_OK;
        }
        
@@ -242,11 +249,19 @@ int arm7_9_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
                /* restore original instruction (kept in target endianness) */
                if (breakpoint->length == 4)
                {
-                       target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
+                       u32 current_instr;
+                       /* check that user program as not modified breakpoint instruction */
+                       target->type->read_memory(target, breakpoint->address, 4, 1, (u8*)&current_instr);
+                       if (current_instr==arm7_9->arm_bkpt)
+                               target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
                }
                else
                {
-                       target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
+                       u16 current_instr;
+                       /* check that user program as not modified breakpoint instruction */
+                       target->type->read_memory(target, breakpoint->address, 2, 1, (u8*)&current_instr);
+                       if (current_instr==arm7_9->thumb_bkpt)
+                               target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
                }
                breakpoint->set = 0;
        }
@@ -261,31 +276,31 @@ int arm7_9_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
        if (arm7_9->force_hw_bkpts)
        {
-               DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint->address);
+               LOG_DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint->address);
                breakpoint->type = BKPT_HARD;
        }
        
        if ((breakpoint->type == BKPT_SOFT) && (arm7_9->sw_bkpts_enabled == 0))
        {
-               INFO("sw breakpoint requested, but software breakpoints not enabled");
+               LOG_INFO("sw breakpoint requested, but software breakpoints not enabled");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
        
        if ((breakpoint->type == BKPT_HARD) && (arm7_9->wp_available < 1))
        {
-               INFO("no watchpoint unit available for hardware breakpoint");
+               LOG_INFO("no watchpoint unit available for hardware breakpoint");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
        
        if ((breakpoint->length != 2) && (breakpoint->length != 4))
        {
-               INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
+               LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
        
@@ -302,7 +317,7 @@ int arm7_9_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
@@ -328,7 +343,7 @@ int arm7_9_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
@@ -367,7 +382,7 @@ int arm7_9_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
        } 
        else
        {
-               ERROR("BUG: no hardware comparator available");
+               LOG_ERROR("BUG: no hardware comparator available");
                return ERROR_OK;
        }
        
@@ -381,13 +396,13 @@ int arm7_9_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
        if (!watchpoint->set)
        {
-               WARNING("breakpoint not set");
+               LOG_WARNING("breakpoint not set");
                return ERROR_OK;
        }
        
@@ -415,7 +430,7 @@ int arm7_9_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
@@ -441,7 +456,7 @@ int arm7_9_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
@@ -466,7 +481,7 @@ int arm7_9_enable_sw_bkpts(struct target_s *target)
        
        if (arm7_9->wp_available < 1)
        {
-               WARNING("can't enable sw breakpoints with no watchpoint unit available");
+               LOG_WARNING("can't enable sw breakpoints with no watchpoint unit available");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
        arm7_9->wp_available--;
@@ -493,14 +508,14 @@ int arm7_9_enable_sw_bkpts(struct target_s *target)
        }
        else
        {
-               ERROR("BUG: both watchpoints used, but wp_available >= 1");
-               exit(-1);
+               LOG_ERROR("BUG: both watchpoints used, but wp_available >= 1");
+               return ERROR_FAIL;
        }
        
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               ERROR("error writing EmbeddedICE registers to enable sw breakpoints");
-               exit(-1);
+               LOG_ERROR("error writing EmbeddedICE registers to enable sw breakpoints");
+               return ERROR_FAIL;
        };
        
        return ERROR_OK;
@@ -544,6 +559,10 @@ int arm7_9_execute_sys_speed(struct target_s *target)
                                
        /* set RESTART instruction */
        jtag_add_end_state(TAP_RTI);
+       if (arm7_9->need_bypass_before_restart) {
+               arm7_9->need_bypass_before_restart = 0;
+               arm_jtag_set_instr(jtag_info, 0xf, NULL);
+       }
        arm_jtag_set_instr(jtag_info, 0x4, NULL);
        
        for (timeout=0; timeout<50; timeout++)
@@ -559,7 +578,7 @@ int arm7_9_execute_sys_speed(struct target_s *target)
        }
        if (timeout == 50)
        {
-               ERROR("timeout waiting for SYSCOMP & DBGACK, last DBG_STATUS: %x", buf_get_u32(dbg_stat->value, 0, dbg_stat->size));
+               LOG_ERROR("timeout waiting for SYSCOMP & DBGACK, last DBG_STATUS: %x", buf_get_u32(dbg_stat->value, 0, dbg_stat->size));
                return ERROR_TARGET_TIMEOUT;
        }
        
@@ -568,7 +587,8 @@ int arm7_9_execute_sys_speed(struct target_s *target)
 
 int arm7_9_execute_fast_sys_speed(struct target_s *target)
 {
-       u8 check_value[4], check_mask[4];
+       static int set=0;
+       static u8 check_value[4], check_mask[4];
        
        armv4_5_common_t *armv4_5 = target->arch_info;
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
@@ -577,11 +597,24 @@ int arm7_9_execute_fast_sys_speed(struct target_s *target)
                                
        /* set RESTART instruction */
        jtag_add_end_state(TAP_RTI);
+       if (arm7_9->need_bypass_before_restart) {
+               arm7_9->need_bypass_before_restart = 0;
+               arm_jtag_set_instr(jtag_info, 0xf, NULL);
+       }
        arm_jtag_set_instr(jtag_info, 0x4, NULL);
        
-       /* check for DBGACK and SYSCOMP set (others don't care) */
-       buf_set_u32(check_value, 0, 32, 0x9);
-       buf_set_u32(check_mask, 0, 32, 0x9);
+       if (!set)
+       {
+               /* check for DBGACK and SYSCOMP set (others don't care) */
+               
+               /* NB! These are constants that must be available until after next jtag_execute() and
+                  we evaluate the values upon first execution in lieu of setting up these constants
+                  during early setup.
+               */
+               buf_set_u32(check_value, 0, 32, 0x9);
+               buf_set_u32(check_mask, 0, 32, 0x9);
+               set=1;
+       }
        
        /* read debug status register */
        embeddedice_read_reg_w_check(dbg_stat, check_value, check_value);
@@ -589,47 +622,112 @@ int arm7_9_execute_fast_sys_speed(struct target_s *target)
        return ERROR_OK;
 }
 
-enum target_state arm7_9_poll(target_t *target)
+int arm7_9_target_request_data(target_t *target, u32 size, u8 *buffer)
 {
-       int retval;
        armv4_5_common_t *armv4_5 = target->arch_info;
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
-       reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
+       arm_jtag_t *jtag_info = &arm7_9->jtag_info;
+       u32 *data;
+       int i;
+       
+       data = malloc(size * (sizeof(u32)));
+       
+       embeddedice_receive(jtag_info, data, size);
+       
+       for (i = 0; i < size; i++)
+       {
+               h_u32_to_le(buffer + (i * 4), data[i]);
+       }
+       
+       free(data);
+       
+       return ERROR_OK;
+}
 
-       if (arm7_9->reinit_embeddedice)
+int arm7_9_handle_target_request(void *priv)
+{
+       target_t *target = priv;
+       if (!target->type->examined)
+               return ERROR_OK;
+       armv4_5_common_t *armv4_5 = target->arch_info;
+       arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+       arm_jtag_t *jtag_info = &arm7_9->jtag_info; 
+       reg_t *dcc_control = &arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL];
+       
+       
+       if (!target->dbg_msg_enabled)
+               return ERROR_OK;
+               
+       if (target->state == TARGET_RUNNING)
        {
-               arm7_9_reinit_embeddedice(target);
+               /* read DCC control register */
+               embeddedice_read_reg(dcc_control);
+               jtag_execute_queue();
+               
+               /* check W bit */
+               if (buf_get_u32(dcc_control->value, 1, 1) == 1)
+               {
+                       u32 request;
+                       
+                       embeddedice_receive(jtag_info, &request, 1);
+                       target_request(target, request);
+               }
        }
        
+       return ERROR_OK;
+}
+
+int arm7_9_poll(target_t *target)
+{
+       int retval;
+       armv4_5_common_t *armv4_5 = target->arch_info;
+       arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+       reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
+
        /* read debug status register */
        embeddedice_read_reg(dbg_stat);
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               switch (retval)
-               {
-                       case ERROR_JTAG_QUEUE_FAILED:
-                               ERROR("JTAG queue failed while reading EmbeddedICE status register");
-                               exit(-1);
-                               break;
-                       default:
-                               break;
-               }
+               return retval;
        }
        
        if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1))
        {
-               DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, 32));
-               if ((target->state == TARGET_UNKNOWN))
+/*             LOG_DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, 32));*/
+               if (target->state == TARGET_UNKNOWN)
                {
-                       WARNING("DBGACK set while target was in unknown state. Reset or initialize target before resuming");
                        target->state = TARGET_RUNNING;
+                       LOG_WARNING("DBGACK set while target was in unknown state. Reset or initialize target.");
                }
                if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
                {
+                       int check_pc=0;
+                       if (target->state == TARGET_RESET)
+                       {
+                               if (target->reset_halt)
+                               {
+                                       if ((jtag_reset_config & RESET_SRST_PULLS_TRST)==0)
+                                       {
+                                               check_pc = 1;
+                                       }
+                               }
+                       }
+                       
                        target->state = TARGET_HALTED;
+                       
                        if ((retval = arm7_9_debug_entry(target)) != ERROR_OK)
                                return retval;
                        
+                       if (check_pc)
+                       {
+                               reg_t *reg = register_get_by_name(target->reg_cache, "pc", 1);
+                               u32 t=*((u32 *)reg->value);
+                               if (t!=0)
+                               {
+                                       LOG_ERROR("PC was not 0. Does this target need srst_pulls_trst?");
+                               }
+                       }
+                       
                        target_call_event_callbacks(target, TARGET_EVENT_HALTED);
                }
                if (target->state == TARGET_DEBUG_RUNNING)
@@ -640,6 +738,10 @@ enum target_state arm7_9_poll(target_t *target)
                        
                        target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
                }
+               if (target->state != TARGET_HALTED)
+               {
+                       LOG_WARNING("DBGACK set, but the target did not end up in the halted stated %d", target->state);
+               }
        }
        else
        {
@@ -647,71 +749,67 @@ enum target_state arm7_9_poll(target_t *target)
                        target->state = TARGET_RUNNING;
        }
        
-       return target->state;
+       return ERROR_OK;
 }
 
+/*
+  Some -S targets (ARM966E-S in the STR912 isn't affected, ARM926EJ-S
+  in the LPC3180 and AT91SAM9260 is affected) completely stop the JTAG clock
+  while the core is held in reset(SRST). It isn't possible to program the halt
+  condition once reset was asserted, hence a hook that allows the target to set
+  up its reset-halt condition prior to asserting reset.
+*/
+
 int arm7_9_assert_reset(target_t *target)
 {
-       int retval;
-       
-       DEBUG("target->state: %s", target_state_strings[target->state]);
+       armv4_5_common_t *armv4_5 = target->arch_info;
+       arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+       LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
        
-       if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
+       if (!(jtag_reset_config & RESET_HAS_SRST))
        {
-               /* if the target wasn't running, there might be working areas allocated */
-               target_free_all_working_areas(target);
-               
-               /* assert SRST and TRST */
-               /* system would get ouf sync if we didn't reset test-logic, too */
-               if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
+               LOG_ERROR("Can't assert SRST");
+               return ERROR_FAIL;
+       }
+
+       if (target->reset_halt)
+       {
+               /*
+                * Some targets do not support communication while SRST is asserted. We need to
+                * set up the reset vector catch here.
+                * 
+                * If TRST is asserted, then these settings will be reset anyway, so setting them
+                * here is harmless.  
+                */
+               if (arm7_9->has_vector_catch)
                {
-                       if (retval == ERROR_JTAG_RESET_CANT_SRST)
-                       {
-                               WARNING("can't assert srst");
-                               return retval;
-                       }
-                       else
-                       {
-                               ERROR("unknown error");
-                               exit(-1);
-                       }
+                       /* program vector catch register to catch reset vector */
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0x1);
                }
-               jtag_add_sleep(5000);
-               if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
+               else
                {
-                       if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
-                       {
-                               WARNING("srst resets test logic, too");
-                               retval = jtag_add_reset(1, 1);
-                       }
+                       /* program watchpoint unit to match on reset vector address */
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], 0x0);
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0x3);
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
                }
        }
-       else
+
+       /* here we should issue a srst only, but we may have to assert trst as well */
+       if (jtag_reset_config & RESET_SRST_PULLS_TRST)
        {
-               if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
-               {
-                       if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
-                       {
-                               WARNING("srst resets test logic, too");
-                               retval = jtag_add_reset(1, 1);
-                       }
-                       
-                       if (retval == ERROR_JTAG_RESET_CANT_SRST)
-                       {
-                               WARNING("can't assert srst");
-                               return retval;
-                       }
-                       else if (retval != ERROR_OK)
-                       {
-                               ERROR("unknown error");
-                               exit(-1);
-                       }
-               }
+               jtag_add_reset(1, 1);
+       } else
+       {
+               jtag_add_reset(0, 1);
        }
        
+
        target->state = TARGET_RESET;
        jtag_add_sleep(50000);
-       
+
        armv4_5_invalidate_core_regs(target);
 
        return ERROR_OK;
@@ -720,7 +818,7 @@ int arm7_9_assert_reset(target_t *target)
 
 int arm7_9_deassert_reset(target_t *target)
 {
-       DEBUG("target->state: %s", target_state_strings[target->state]);
+       LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
        
        /* deassert reset lines */
        jtag_add_reset(0, 0);
@@ -758,6 +856,10 @@ int arm7_9_clear_halt(target_t *target)
                         */
                        if (arm7_9->wp0_used)
                        {
+                               if (arm7_9->debug_entry_from_reset)
+                               {
+                                       embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE]);
+                               }
                                embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
                                embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
                                embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
@@ -779,16 +881,26 @@ int arm7_9_soft_reset_halt(struct target_s *target)
        reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
        reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
        int i;
+       int retval;
        
-       if (target->state == TARGET_RUNNING)
-       {
-               target->type->halt(target);
-       }
+       if ((retval=target_halt(target))!=ERROR_OK)
+               return retval;
        
-       while (buf_get_u32(dbg_stat->value, EICE_DBG_CONTROL_DBGACK, 1) == 0)
+       for (i=0; i<10; i++)
        {
+               if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) != 0)
+                       break;
                embeddedice_read_reg(dbg_stat);
-               jtag_execute_queue();
+               if ((retval=jtag_execute_queue())!=ERROR_OK)
+                       return retval;
+               /* do not eat all CPU, time out after 1 se*/
+               usleep(100*1000);
+               
+       }
+       if (i==10)
+       {
+               LOG_ERROR("Failed to halt CPU after 1 sec");
+               return ERROR_TARGET_TIMEOUT;
        }
        target->state = TARGET_HALTED;
        
@@ -806,7 +918,7 @@ int arm7_9_soft_reset_halt(struct target_s *target)
        if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1))
        {
                u32 r0_thumb, pc_thumb;
-               DEBUG("target entered debug from Thumb state, changing to ARM");
+               LOG_DEBUG("target entered debug from Thumb state, changing to ARM");
                /* Entered debug from Thumb mode */
                armv4_5->core_state = ARMV4_5_STATE_THUMB;
                arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
@@ -827,6 +939,9 @@ int arm7_9_soft_reset_halt(struct target_s *target)
        
        armv4_5->core_mode = ARMV4_5_MODE_SVC;
        armv4_5->core_state = ARMV4_5_STATE_ARM;
+
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
        
        /* reset registers */
        for (i = 0; i <= 14; i++)
@@ -841,58 +956,36 @@ int arm7_9_soft_reset_halt(struct target_s *target)
        return ERROR_OK;
 }
 
-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;
-       
-       if (arm7_9->has_vector_catch)
-       {
-               /* program vector catch register to catch reset vector */
-               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0x1);
-       }
-       else
-       {
-               /* program watchpoint unit to match on reset vector address */
-               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0x3);
-               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0x0);
-               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
-               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
-       }
-       
-       return ERROR_OK;
-}
-
 int arm7_9_halt(target_t *target)
 {
        armv4_5_common_t *armv4_5 = target->arch_info;
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
        reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
        
-       DEBUG("target->state: %s", target_state_strings[target->state]);
+       LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
        
        if (target->state == TARGET_HALTED)
        {
-               WARNING("target was already halted");
-               return ERROR_TARGET_ALREADY_HALTED;
+               LOG_DEBUG("target was already halted");
+               return ERROR_OK;
        }
        
        if (target->state == TARGET_UNKNOWN)
        {
-               WARNING("target was in unknown state when halt was requested");
+               LOG_WARNING("target was in unknown state when halt was requested");
        }
        
        if (target->state == TARGET_RESET) 
        {
                if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
                {
-                       ERROR("can't request a halt while in reset if nSRST pulls nTRST");
+                       LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
                        return ERROR_TARGET_FAILURE;
                }
                else
                {
                        /* we came here in a reset_halt or reset_init sequence
-                        * debug entry was already prepared in arm7_9_prepare_reset_halt()
+                        * debug entry was already prepared in arm7_9_assert_reset()
                         */
                        target->debug_reason = DBG_REASON_DBGRQ;
                        
@@ -904,8 +997,12 @@ int arm7_9_halt(target_t *target)
        {
                /* program EmbeddedICE Debug Control Register to assert DBGRQ
                 */
-               buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1);     
-               embeddedice_store_reg(dbg_ctrl);
+               if (arm7_9->set_special_dbgrq) {
+                       arm7_9->set_special_dbgrq(target);
+               } else {
+                       buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1);     
+                       embeddedice_store_reg(dbg_ctrl);
+               }
        }
        else
        {
@@ -913,8 +1010,8 @@ int arm7_9_halt(target_t *target)
                 */
                embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);
                embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
-               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
-               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
        }
 
        target->debug_reason = DBG_REASON_DBGRQ;
@@ -937,7 +1034,7 @@ int arm7_9_debug_entry(target_t *target)
        reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
 
 #ifdef _DEBUG_ARM7_9_
-       DEBUG("-");
+       LOG_DEBUG("-");
 #endif
 
        if (arm7_9->pre_debug_entry)
@@ -955,15 +1052,7 @@ int arm7_9_debug_entry(target_t *target)
        
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               switch (retval)
-               {
-                       case ERROR_JTAG_QUEUE_FAILED:
-                               ERROR("JTAG queue failed while writing EmbeddedICE control register");
-                               exit(-1);
-                               break;
-                       default:
-                               break;
-               }
+               return retval;
        }
 
        if ((retval = arm7_9->examine_debug_reason(target)) != ERROR_OK)
@@ -972,22 +1061,22 @@ int arm7_9_debug_entry(target_t *target)
 
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
        /* if the target is in Thumb state, change to ARM state */
        if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1))
        {
-               DEBUG("target entered debug from Thumb state");
+               LOG_DEBUG("target entered debug from Thumb state");
                /* Entered debug from Thumb mode */
                armv4_5->core_state = ARMV4_5_STATE_THUMB;
                arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
-               DEBUG("r0_thumb: 0x%8.8x, pc_thumb: 0x%8.8x", r0_thumb, pc_thumb);
+               LOG_DEBUG("r0_thumb: 0x%8.8x, pc_thumb: 0x%8.8x", r0_thumb, pc_thumb);
        }
        else
        {
-               DEBUG("target entered debug from ARM state");
+               LOG_DEBUG("target entered debug from ARM state");
                /* Entered debug from ARM mode */
                armv4_5->core_state = ARMV4_5_STATE_ARM;
        }
@@ -1015,15 +1104,15 @@ int arm7_9_debug_entry(target_t *target)
        if (armv4_5_mode_to_number(armv4_5->core_mode) == -1)
        {
                target->state = TARGET_UNKNOWN;
-               ERROR("cpsr contains invalid mode value - communication failure");
+               LOG_ERROR("cpsr contains invalid mode value - communication failure");
                return ERROR_TARGET_FAILURE;
        }
 
-       DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
+       LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
        
        if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
        {
-               DEBUG("thumb state, applying fixups");
+               LOG_DEBUG("thumb state, applying fixups");
                context[0] = r0_thumb;
                context[15] = pc_thumb;
        } else if (armv4_5->core_state == ARMV4_5_STATE_ARM)
@@ -1042,22 +1131,27 @@ int arm7_9_debug_entry(target_t *target)
                context[15] -= arm7_9->dbgreq_adjust_pc * ((armv4_5->core_state == ARMV4_5_STATE_ARM) ? 4 : 2);
        else
        {
-               ERROR("unknown debug reason: %i", target->debug_reason);
+               LOG_ERROR("unknown debug reason: %i", target->debug_reason);
        }
 
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
        
        for (i=0; i<=15; i++)
        {
-               DEBUG("r%i: 0x%8.8x", i, context[i]);
+               LOG_DEBUG("r%i: 0x%8.8x", i, context[i]);
                buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, context[i]);
                ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 0;
                ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
        }
        
-       DEBUG("entered debug state at PC 0x%x", context[15]);
+       LOG_DEBUG("entered debug state at PC 0x%x", context[15]);
+       
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
 
        /* exceptions other than USR & SYS have a saved program status register */
-       if ((armv4_5_mode_to_number(armv4_5->core_mode) != ARMV4_5_MODE_USR) && (armv4_5_mode_to_number(armv4_5->core_mode) != ARMV4_5_MODE_SYS))
+       if ((armv4_5->core_mode != ARMV4_5_MODE_USR) && (armv4_5->core_mode != ARMV4_5_MODE_SYS))
        {
                u32 spsr;
                arm7_9->read_xpsr(target, &spsr, 1);
@@ -1068,10 +1162,10 @@ int arm7_9_debug_entry(target_t *target)
        }
 
        /* r0 and r15 (pc) have to be restored later */
-       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
-       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).dirty = 1;
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).valid;
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).valid;
 
-       if ((retval = jtag->execute_queue()) != ERROR_OK)
+       if ((retval = jtag_execute_queue()) != ERROR_OK)
                return retval;
 
        if (arm7_9->post_debug_entry)
@@ -1087,13 +1181,16 @@ int arm7_9_full_context(target_t *target)
        armv4_5_common_t *armv4_5 = target->arch_info;
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
 
-       DEBUG("-");
+       LOG_DEBUG("-");
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
+       
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
 
        /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)
         * SYS shares registers with User, so we don't touch SYS
@@ -1153,8 +1250,7 @@ int arm7_9_full_context(target_t *target)
        
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               ERROR("JTAG failure");
-               exit(-1);
+               return retval;
        }
        return ERROR_OK;
 }
@@ -1170,23 +1266,26 @@ int arm7_9_restore_context(target_t *target)
        int dirty;
        int mode_change;
        
-       DEBUG("-");
+       LOG_DEBUG("-");
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
        if (arm7_9->pre_restore_context)
                arm7_9->pre_restore_context(target);
        
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
+               
        /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)
         * SYS shares registers with User, so we don't touch SYS
         */
        for (i = 0; i < 6; i++)
        {
-               DEBUG("examining %s mode", armv4_5_mode_strings[i]);
+               LOG_DEBUG("examining %s mode", armv4_5_mode_strings[i]);
                dirty = 0;
                mode_change = 0;
                /* check if there are dirty registers in the current mode 
@@ -1200,20 +1299,19 @@ int arm7_9_restore_context(target_t *target)
                                if (reg->valid == 1)
                                {
                                        dirty = 1;
-                                       DEBUG("examining dirty reg: %s", reg->name);
+                                       LOG_DEBUG("examining dirty reg: %s", reg->name);
                                        if ((reg_arch_info->mode != ARMV4_5_MODE_ANY)
                                                && (reg_arch_info->mode != current_mode)
                                                && !((reg_arch_info->mode == ARMV4_5_MODE_USR) && (armv4_5->core_mode == ARMV4_5_MODE_SYS)) 
                                                && !((reg_arch_info->mode == ARMV4_5_MODE_SYS) && (armv4_5->core_mode == ARMV4_5_MODE_USR)))
                                        {
                                                mode_change = 1;
-                                               DEBUG("require mode change");
+                                               LOG_DEBUG("require mode change");
                                        }
                                }
                                else
                                {
-                                       ERROR("BUG: dirty register '%s', but no valid data", reg->name);
-                                       exit(-1);
+                                       LOG_ERROR("BUG: dirty register '%s', but no valid data", reg->name);
                                }
                        }
                }
@@ -1249,7 +1347,7 @@ int arm7_9_restore_context(target_t *target)
                                        num_regs++;
                                        reg->dirty = 0;
                                        reg->valid = 1;
-                                       DEBUG("writing register %i of mode %s with value 0x%8.8x", j, armv4_5_mode_strings[i], regs[j]);
+                                       LOG_DEBUG("writing register %i of mode %s with value 0x%8.8x", j, armv4_5_mode_strings[i], regs[j]);
                                }
                        }
                        
@@ -1262,7 +1360,7 @@ int arm7_9_restore_context(target_t *target)
                        reg_arch_info = reg->arch_info;
                        if ((reg->dirty) && (reg_arch_info->mode != ARMV4_5_MODE_ANY))
                        {
-                               DEBUG("writing SPSR of mode %i with value 0x%8.8x", i, buf_get_u32(reg->value, 0, 32));
+                               LOG_DEBUG("writing SPSR of mode %i with value 0x%8.8x", i, buf_get_u32(reg->value, 0, 32));
                                arm7_9->write_xpsr(target, buf_get_u32(reg->value, 0, 32), 1);
                        }
                }
@@ -1276,20 +1374,20 @@ int arm7_9_restore_context(target_t *target)
                tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
                tmp_cpsr |= armv4_5_number_to_mode(i);
                tmp_cpsr &= ~0x20;
-               DEBUG("writing lower 8 bit of cpsr with value 0x%2.2x", tmp_cpsr);
+               LOG_DEBUG("writing lower 8 bit of cpsr with value 0x%2.2x", tmp_cpsr);
                arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
        }
        else if (armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty == 1)
        {
                /* CPSR has been changed, full restore necessary (mask T bit) */
-               DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
+               LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
                arm7_9->write_xpsr(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32) & ~0x20, 0);
                armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 0;
                armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
        }
        
        /* restore PC */
-       DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
+       LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
        arm7_9->write_pc(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
        armv4_5->core_cache->reg_list[15].dirty = 0;
                        
@@ -1307,15 +1405,14 @@ int arm7_9_restart_core(struct target_s *target)
        
        /* set RESTART instruction */
        jtag_add_end_state(TAP_RTI);
+       if (arm7_9->need_bypass_before_restart) {
+               arm7_9->need_bypass_before_restart = 0;
+               arm_jtag_set_instr(jtag_info, 0xf, NULL);
+       }
        arm_jtag_set_instr(jtag_info, 0x4, NULL);
        
        jtag_add_runtest(1, TAP_RTI);
-       if ((jtag_execute_queue()) != ERROR_OK)
-       {
-               exit(-1);
-       }
-       
-       return ERROR_OK;
+       return jtag_execute_queue();
 }
 
 void arm7_9_enable_watchpoints(struct target_s *target)
@@ -1370,12 +1467,13 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
        breakpoint_t *breakpoint = target->breakpoints;
        reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
+       int err;
        
-       DEBUG("-");
+       LOG_DEBUG("-");
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
@@ -1393,10 +1491,10 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_
        {
                if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
                {
-                       DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
+                       LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
                        arm7_9_unset_breakpoint(target, breakpoint);
                        
-                       DEBUG("enable single-step");
+                       LOG_DEBUG("enable single-step");
                        arm7_9->enable_single_step(target);
                        
                        target->debug_reason = DBG_REASON_SINGLESTEP;
@@ -1411,21 +1509,28 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_
                        }
                        else
                        {
-                               ERROR("unhandled core state");
-                               exit(-1);
+                               LOG_ERROR("unhandled core state");
+                               return ERROR_FAIL;
                        }
                                
                        buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
                        embeddedice_write_reg(dbg_ctrl, buf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size));
-                       arm7_9_execute_sys_speed(target);
+                       err = arm7_9_execute_sys_speed(target);
                        
-                       DEBUG("disable single-step");
+                       LOG_DEBUG("disable single-step");
                        arm7_9->disable_single_step(target);
-                       
+
+                       if (err != ERROR_OK)
+                       {
+                               arm7_9_set_breakpoint(target, breakpoint);
+                               target->state = TARGET_UNKNOWN;
+                               return err;
+                       }
+
                        arm7_9_debug_entry(target);
-                       DEBUG("new PC after step: 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
-               
-                       DEBUG("set breakpoint at 0x%8.8x", breakpoint->address);
+                       LOG_DEBUG("new PC after step: 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
+
+                       LOG_DEBUG("set breakpoint at 0x%8.8x", breakpoint->address);
                        arm7_9_set_breakpoint(target, breakpoint);
                }
        }
@@ -1446,8 +1551,8 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_
        }
        else
        {
-               ERROR("unhandled core state");
-               exit(-1);
+               LOG_ERROR("unhandled core state");
+               return ERROR_FAIL;
        }
        
        /* deassert DBGACK and INTDIS */
@@ -1474,7 +1579,7 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_
                target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
        }
        
-       DEBUG("target resumed");
+       LOG_DEBUG("target resumed");
        
        return ERROR_OK;
 }
@@ -1490,13 +1595,13 @@ void arm7_9_enable_eice_step(target_t *target)
        * - comparator 0 matches any address, as long as rangein is low */
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
-       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
-       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0x77);
+       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
+       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~(EICE_W_CTRL_RANGE|EICE_W_CTRL_nOPC) & 0xff);
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0);
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffff);
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
-       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], 0xf7);
+       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
 }
 
 void arm7_9_disable_eice_step(target_t *target)
@@ -1520,10 +1625,11 @@ int arm7_9_step(struct target_s *target, int current, u32 address, int handle_br
        armv4_5_common_t *armv4_5 = target->arch_info;
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
        breakpoint_t *breakpoint = NULL;
+       int err;
 
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
@@ -1552,28 +1658,31 @@ int arm7_9_step(struct target_s *target, int current, u32 address, int handle_br
        }
        else
        {
-               ERROR("unhandled core state");
-               exit(-1);
+               LOG_ERROR("unhandled core state");
+               return ERROR_FAIL;
        }
        
        target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
 
-       arm7_9_execute_sys_speed(target);
+       err = arm7_9_execute_sys_speed(target);
        arm7_9->disable_single_step(target);
        
        /* registers are now invalid */
        armv4_5_invalidate_core_regs(target);
        
-       arm7_9_debug_entry(target);
+       if (err != ERROR_OK)
+       {
+               target->state = TARGET_UNKNOWN;
+       } else {
+               arm7_9_debug_entry(target);
+               target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+               LOG_DEBUG("target stepped");
+       }
        
-       target_call_event_callbacks(target, TARGET_EVENT_HALTED);
-
        if (breakpoint)
                arm7_9_set_breakpoint(target, breakpoint);
        
-       DEBUG("target stepped");
-
-       return ERROR_OK;
+       return err;
 
 }
 
@@ -1584,6 +1693,10 @@ int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mod
        int retval;
        armv4_5_common_t *armv4_5 = target->arch_info;
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+       
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
+       
        enum armv4_5_mode reg_mode = ((armv4_5_core_reg_t*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode;
        
        if ((num < 0) || (num > 16))
@@ -1622,8 +1735,7 @@ int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mod
        
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               ERROR("JTAG failure");
-               exit(-1);
+               return retval;
        }
                
        ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
@@ -1644,9 +1756,12 @@ int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mod
 int arm7_9_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, u32 value)
 {
        u32 reg[16];
-       int retval;
        armv4_5_common_t *armv4_5 = target->arch_info;
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+       
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
+       
        enum armv4_5_mode reg_mode = ((armv4_5_core_reg_t*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode;
 
        if ((num < 0) || (num > 16))
@@ -1696,14 +1811,7 @@ int arm7_9_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mo
                arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
        }
        
-       if ((retval = jtag_execute_queue()) != ERROR_OK)
-       {
-               ERROR("JTAG failure");
-               exit(-1);
-       }
-       
-       return ERROR_OK;
-       
+       return jtag_execute_queue();
 }
 
 int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
@@ -1719,11 +1827,11 @@ int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count
        int retval;
        int last_reg = 0;
        
-       DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
+       LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
 
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
@@ -1824,24 +1932,27 @@ int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count
                        }       
                        break;
                default:
-                       ERROR("BUG: we shouldn't get here");
+                       LOG_ERROR("BUG: we shouldn't get here");
                        exit(-1);
                        break;
        }
        
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
+
        for (i=0; i<=last_reg; i++)
-               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 1;
+               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid;
 
        arm7_9->read_xpsr(target, &cpsr, 0);
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               ERROR("JTAG error while reading cpsr");
-               exit(-1);
+               LOG_ERROR("JTAG error while reading cpsr");
+               return ERROR_TARGET_DATA_ABORT;
        }
 
        if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
        {
-               WARNING("memory read caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
+               LOG_WARNING("memory read caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
 
                arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
 
@@ -1865,11 +1976,13 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun
        int retval;
        int last_reg = 0;
 
-       DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
+#ifdef _DEBUG_ARM7_9_
+       LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
+#endif
 
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
@@ -1985,7 +2098,7 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun
                        }       
                        break;
                default:
-                       ERROR("BUG: we shouldn't get here");
+                       LOG_ERROR("BUG: we shouldn't get here");
                        exit(-1);
                        break;
        }
@@ -1994,19 +2107,22 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun
        buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
        embeddedice_store_reg(dbg_ctrl);
        
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
+
        for (i=0; i<=last_reg; i++)
-               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 1;
+               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid;
 
        arm7_9->read_xpsr(target, &cpsr, 0);
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               ERROR("JTAG error while reading cpsr");
-               exit(-1);
+               LOG_ERROR("JTAG error while reading cpsr");
+               return ERROR_TARGET_DATA_ABORT;
        }
 
        if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
        {
-               WARNING("memory write caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
+               LOG_WARNING("memory write caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
 
                arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
 
@@ -2016,6 +2132,12 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun
        return ERROR_OK;
 }
 
+static const u32 dcc_code[] = 
+{
+       /* MRC      TST         BNE         MRC         STR         B */
+       0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9
+};
+
 int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
 {
        armv4_5_common_t *armv4_5 = target->arch_info;
@@ -2026,12 +2148,6 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe
        u32 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
        int i;
        
-       u32 dcc_code[] = 
-       {
-               /* MRC      TST         BNE         MRC         STR         B */
-               0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9
-       };
-       
        if (!arm7_9->dcc_downloads)
                return target->type->write_memory(target, address, 4, count, buffer);
 
@@ -2043,7 +2159,7 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe
                /* make sure we have a working area */
                if (target_alloc_working_area(target, 24, &arm7_9->dcc_working_area) != ERROR_OK)
                {
-                       INFO("no working area available, falling back to memory writes");
+                       LOG_INFO("no working area available, falling back to memory writes");
                        return target->type->write_memory(target, address, 4, count, buffer);
                }
                
@@ -2064,16 +2180,60 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe
 
        arm7_9_resume(target, 0, arm7_9->dcc_working_area->address, 1, 1);
        
-       for (i = 0; i < count; i++)
+       int little=target->endianness==TARGET_LITTLE_ENDIAN;
+       if (count>2)
+       {
+               /* Handle first & last using standard embeddedice_write_reg and the middle ones w/the
+                  core function repeated. 
+                */
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little));
+               buffer+=4;
+               
+               embeddedice_reg_t *ice_reg = arm7_9->eice_cache->reg_list[EICE_COMMS_DATA].arch_info;
+               u8 reg_addr = ice_reg->addr & 0x1f;
+               int chain_pos = ice_reg->jtag_info->chain_pos;
+               /* we want the compiler to duplicate the code, which it does not
+                * do automatically.
+                */
+               if (little)
+               {
+                       for (i = 1; i < count - 1; i++)
+                       {
+                               embeddedice_write_reg_inner(chain_pos, reg_addr, fast_target_buffer_get_u32(buffer, little));
+                               buffer += 4;
+                       }
+               } else
+               {
+                       for (i = 1; i < count - 1; i++)
+                       {
+                               embeddedice_write_reg_inner(chain_pos, reg_addr, fast_target_buffer_get_u32(buffer, little));
+                               buffer += 4;
+                       }
+               }
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little));
+       } else
        {
-               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], target_buffer_get_u32(target, buffer));
-               buffer += 4;
+               for (i = 0; i < count; i++)
+               {
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little));
+                       buffer += 4;
+               }
        }
        
-       target->type->halt(target);
+       target_halt(target);
        
-       while (target->state != TARGET_HALTED)
-               target->type->poll(target);
+       for (i=0; i<100; i++)
+       {
+               target_poll(target);
+               if (target->state == TARGET_HALTED)
+                       break;
+               usleep(1000); /* sleep 1ms */
+       }
+       if (i == 100)
+       {
+               LOG_ERROR("bulk write timed out, target not halted");
+               return ERROR_TARGET_TIMEOUT;
+       }
        
        /* restore target state */
        buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, r0);
@@ -2090,14 +2250,151 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe
        return ERROR_OK;
 }
 
+int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
+{
+       working_area_t *crc_algorithm;
+       armv4_5_algorithm_t armv4_5_info;
+       reg_param_t reg_params[2];
+       int retval;
+       
+       u32 arm7_9_crc_code[] = {
+               0xE1A02000,                             /* mov          r2, r0 */
+               0xE3E00000,                             /* mov          r0, #0xffffffff */
+               0xE1A03001,                             /* mov          r3, r1 */
+               0xE3A04000,                             /* mov          r4, #0 */
+               0xEA00000B,                             /* b            ncomp */
+                                                               /* nbyte: */
+               0xE7D21004,                             /* ldrb r1, [r2, r4] */
+               0xE59F7030,                             /* ldr          r7, CRC32XOR */
+               0xE0200C01,                             /* eor          r0, r0, r1, asl 24 */
+               0xE3A05000,                             /* mov          r5, #0 */
+                                                               /* loop: */
+               0xE3500000,                             /* cmp          r0, #0 */
+               0xE1A06080,                             /* mov          r6, r0, asl #1 */
+               0xE2855001,                             /* add          r5, r5, #1 */
+               0xE1A00006,                             /* mov          r0, r6 */
+               0xB0260007,                             /* eorlt        r0, r6, r7 */
+               0xE3550008,                             /* cmp          r5, #8 */
+               0x1AFFFFF8,                             /* bne          loop */
+               0xE2844001,                             /* add          r4, r4, #1 */
+                                                               /* ncomp: */
+               0xE1540003,                             /* cmp          r4, r3 */
+               0x1AFFFFF1,                             /* bne          nbyte */
+                                                               /* end: */
+               0xEAFFFFFE,                             /* b            end */
+               0x04C11DB7                              /* CRC32XOR:    .word 0x04C11DB7 */
+       };
+       
+       int i;
+       
+       if (target_alloc_working_area(target, sizeof(arm7_9_crc_code), &crc_algorithm) != ERROR_OK)
+       {
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+       }
+       
+       /* convert flash writing code into a buffer in target endianness */
+       for (i = 0; i < (sizeof(arm7_9_crc_code)/sizeof(u32)); i++)
+               target_write_u32(target, crc_algorithm->address + i*sizeof(u32), arm7_9_crc_code[i]);
+       
+       armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
+       armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
+       armv4_5_info.core_state = ARMV4_5_STATE_ARM;
+       
+       init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
+       init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
+       
+       buf_set_u32(reg_params[0].value, 0, 32, address);
+       buf_set_u32(reg_params[1].value, 0, 32, count);
+               
+       if ((retval = target->type->run_algorithm(target, 0, NULL, 2, reg_params,
+               crc_algorithm->address, crc_algorithm->address + (sizeof(arm7_9_crc_code) - 8), 20000, &armv4_5_info)) != ERROR_OK)
+       {
+               LOG_ERROR("error executing arm7_9 crc algorithm");
+               destroy_reg_param(&reg_params[0]);
+               destroy_reg_param(&reg_params[1]);
+               target_free_working_area(target, crc_algorithm);
+               return retval;
+       }
+       
+       *checksum = buf_get_u32(reg_params[0].value, 0, 32);
+       
+       destroy_reg_param(&reg_params[0]);
+       destroy_reg_param(&reg_params[1]);
+       
+       target_free_working_area(target, crc_algorithm);
+       
+       return ERROR_OK;
+}
+
+int arm7_9_blank_check_memory(struct target_s *target, u32 address, u32 count, u32* blank)
+{
+       working_area_t *erase_check_algorithm;
+       reg_param_t reg_params[3];
+       armv4_5_algorithm_t armv4_5_info;
+       int retval;
+       int i;
+       
+       u32 erase_check_code[] =
+       {
+                                               /* loop: */
+               0xe4d03001,             /* ldrb r3, [r0], #1    */
+               0xe0022003,             /* and r2, r2, r3               */
+               0xe2511001,     /* subs r1, r1, #1              */
+               0x1afffffb,             /* bne loop                             */
+                                               /* end: */
+               0xeafffffe              /* b end                                */
+       };
+
+       /* make sure we have a working area */
+       if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
+       {
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+       }
+       
+       /* convert flash writing code into a buffer in target endianness */
+       for (i = 0; i < (sizeof(erase_check_code)/sizeof(u32)); i++)
+               target_write_u32(target, erase_check_algorithm->address + i*sizeof(u32), erase_check_code[i]);
+       
+       armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
+       armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
+       armv4_5_info.core_state = ARMV4_5_STATE_ARM;
+
+       init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
+       buf_set_u32(reg_params[0].value, 0, 32, address);
+
+       init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
+       buf_set_u32(reg_params[1].value, 0, 32, count);
+
+       init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
+       buf_set_u32(reg_params[2].value, 0, 32, 0xff);
+       
+       if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params, 
+                       erase_check_algorithm->address, erase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &armv4_5_info)) != ERROR_OK)
+       {
+               destroy_reg_param(&reg_params[0]);
+               destroy_reg_param(&reg_params[1]);
+               destroy_reg_param(&reg_params[2]);
+               target_free_working_area(target, erase_check_algorithm);
+               return 0;
+       }
+       
+       *blank = buf_get_u32(reg_params[2].value, 0, 32);
+       
+       destroy_reg_param(&reg_params[0]);
+       destroy_reg_param(&reg_params[1]);
+       destroy_reg_param(&reg_params[2]);
+       
+       target_free_working_area(target, erase_check_algorithm);
+       
+       return ERROR_OK;
+}
+
 int arm7_9_register_commands(struct command_context_s *cmd_ctx)
 {
        command_t *arm7_9_cmd;
        
        arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, "arm7/9 specific commands");
 
-       register_command(cmd_ctx, arm7_9_cmd, "etm", handle_arm7_9_etm_command, COMMAND_CONFIG, NULL);
-       
        register_command(cmd_ctx, arm7_9_cmd, "write_xpsr", handle_arm7_9_write_xpsr_command, COMMAND_EXEC, "write program status register <value> <not cpsr|spsr>");
        register_command(cmd_ctx, arm7_9_cmd, "write_xpsr_im8", handle_arm7_9_write_xpsr_im8_command, COMMAND_EXEC, "write program status register <8bit immediate> <rotate> <not cpsr|spsr>");
        
@@ -2115,7 +2412,8 @@ int arm7_9_register_commands(struct command_context_s *cmd_ctx)
                COMMAND_ANY, "use DCC downloads for larger memory writes <enable|disable>");
 
        armv4_5_register_commands(cmd_ctx);
-       etb_register_commands(cmd_ctx, arm7_9_cmd);
+       
+       etm_register_commands(cmd_ctx);
        
        return ERROR_OK;
 }
@@ -2157,8 +2455,8 @@ int handle_arm7_9_write_xpsr_command(struct command_context_s *cmd_ctx, char *cm
        arm7_9->write_xpsr(target, value, spsr);
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               ERROR("JTAG error while writing to xpsr");
-               exit(-1);
+               LOG_ERROR("JTAG error while writing to xpsr");
+               return retval;
        }
        
        return ERROR_OK;
@@ -2199,8 +2497,8 @@ int handle_arm7_9_write_xpsr_im8_command(struct command_context_s *cmd_ctx, char
        arm7_9->write_xpsr_im8(target, value, rotate, spsr);
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               ERROR("JTAG error while writing 8-bit immediate to xpsr");
-               exit(-1);
+               LOG_ERROR("JTAG error while writing 8-bit immediate to xpsr");
+               return retval;
        }
        
        return ERROR_OK;
@@ -2248,6 +2546,12 @@ int handle_arm7_9_sw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd,
        armv4_5_common_t *armv4_5;
        arm7_9_common_t *arm7_9;
        
+       if (target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+       
        if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
        {
                command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
@@ -2425,81 +2729,6 @@ int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char
        return ERROR_OK;
 }
 
-int handle_arm7_9_etm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target;
-       armv4_5_common_t *armv4_5;
-       arm7_9_common_t *arm7_9;
-       
-       if (argc != 1)
-       {
-               ERROR("incomplete 'arm7_9 etm <target>' command");
-               exit(-1);
-       }
-       
-       target = get_target_by_num(strtoul(args[0], NULL, 0));
-       
-       if (!target)
-       {
-               ERROR("target number '%s' not defined", args[0]);
-               exit(-1);
-       }
-       
-       if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
-       {
-               command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_OK;
-       }
-       
-       arm7_9->has_etm = 1;
-       
-       return ERROR_OK;
-}
-
-int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target;
-       jtag_device_t *jtag_device;
-       armv4_5_common_t *armv4_5;
-       arm7_9_common_t *arm7_9;
-       
-       if (argc != 2)
-       {
-               ERROR("incomplete 'arm7_9 etb <target> <chain_pos>' command");
-               exit(-1);
-       }
-       
-       target = get_target_by_num(strtoul(args[0], NULL, 0));
-       
-       if (!target)
-       {
-               ERROR("target number '%s' not defined", args[0]);
-               exit(-1);
-       }
-       
-       if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
-       {
-               command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_OK;
-       }
-       
-       jtag_device = jtag_get_device(strtoul(args[1], NULL, 0));
-       
-       if (!jtag_device)
-       {
-               ERROR("jtag device number '%s' not defined", args[1]);
-               exit(-1);
-       }
-
-       arm7_9->etb = malloc(sizeof(etb_t));
-       
-       arm7_9->etb->chain_pos = strtoul(args[1], NULL, 0);
-       arm7_9->etb->cur_scan_chain = -1;
-       arm7_9->etb->reg_cache = NULL;
-
-       return ERROR_OK;
-}
-
 int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
 {
        armv4_5_common_t *armv4_5 = &arm7_9->armv4_5_common;
@@ -2513,23 +2742,20 @@ int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
        arm7_9->force_hw_bkpts = 0;
        arm7_9->use_dbgrq = 0;
        
-       arm7_9->has_etm = 0;
-       arm7_9->etb = NULL;
+       arm7_9->etm_ctx = NULL;
        arm7_9->has_single_step = 0;
        arm7_9->has_monitor_mode = 0;
        arm7_9->has_vector_catch = 0;
        
-       arm7_9->reinit_embeddedice = 0;
-       
        arm7_9->debug_entry_from_reset = 0;
        
        arm7_9->dcc_working_area = NULL;
        
-       arm7_9->fast_memory_access = 0;
-       arm7_9->dcc_downloads = 0;
-
-       jtag_register_event_callback(arm7_9_jtag_callback, target);
-
+       arm7_9->fast_memory_access = fast_and_dangerous;
+       arm7_9->dcc_downloads = fast_and_dangerous;
+       
+       arm7_9->need_bypass_before_restart = 0;
+       
        armv4_5->arch_info = arm7_9;
        armv4_5->read_core_reg = arm7_9_read_core_reg;
        armv4_5->write_core_reg = arm7_9_write_core_reg;
@@ -2537,5 +2763,7 @@ int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
        
        armv4_5_init_arch_info(target, armv4_5);
        
+       target_register_timer_callback(arm7_9_handle_target_request, 1, 1, target);
+       
        return ERROR_OK;
 }