- jtag_khz/speed are now single parameter only. These are used
[fw/openocd] / src / target / arm7_9_common.c
index 5ce1db5671d50d254448c9826fcd74382a73143b..563f470159682725ed59be87f5980a19c1e6d63a 100644 (file)
@@ -84,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)
@@ -135,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;
        }
        
@@ -144,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;
        }
 
@@ -178,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;
                }
        }
@@ -195,7 +185,7 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
                        target->type->read_memory(target, breakpoint->address, 4, 1, (u8 *)&verify);
                        if (verify != arm7_9->arm_bkpt)
                        {
-                               ERROR("Unable to set 32 bit software breakpoint at address %08x", breakpoint->address);
+                               LOG_ERROR("Unable to set 32 bit software breakpoint at address %08x - check that memory is read/writable", breakpoint->address);
                                return ERROR_OK;
                        }
                }
@@ -210,7 +200,7 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
                        target->type->read_memory(target, breakpoint->address, 2, 1, (u8 *)&verify);
                        if (verify != arm7_9->thumb_bkpt)
                        {
-                               ERROR("Unable to set thumb software breakpoint at address %08x", breakpoint->address);
+                               LOG_ERROR("Unable to set thumb software breakpoint at address %08x - check that memory is read/writable", breakpoint->address);
                                return ERROR_OK;
                        }
                }
@@ -228,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;
        }
        
@@ -286,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;
        }
        
@@ -327,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;
        }
        
@@ -353,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;
        }
        
@@ -392,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;
        }
        
@@ -406,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;
        }
        
@@ -440,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;
        }
        
@@ -466,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;
        }
        
@@ -491,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--;
@@ -518,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;
@@ -569,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++)
@@ -584,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;
        }
        
@@ -603,6 +597,10 @@ 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);
        
        if (!set)
@@ -649,11 +647,14 @@ int arm7_9_target_request_data(target_t *target, u32 size, u8 *buffer)
 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;
                
@@ -683,11 +684,6 @@ int arm7_9_poll(target_t *target)
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
        reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
 
-       if (arm7_9->reinit_embeddedice)
-       {
-               arm7_9_reinit_embeddedice(target);
-       }
-       
        /* read debug status register */
        embeddedice_read_reg(dbg_stat);
        if ((retval = jtag_execute_queue()) != ERROR_OK)
@@ -697,18 +693,41 @@ int arm7_9_poll(target_t *target)
        
        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));
+/*             LOG_DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, 32));*/
                if (target->state == TARGET_UNKNOWN)
                {
                        target->state = TARGET_RUNNING;
-                       WARNING("DBGACK set while target was in unknown state. Reset or initialize target.");
+                       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)
@@ -721,7 +740,7 @@ int arm7_9_poll(target_t *target)
                }
                if (target->state != TARGET_HALTED)
                {
-                       WARNING("DBGACK set, but the target did not end up in the halted stated %d", target->state);
+                       LOG_WARNING("DBGACK set, but the target did not end up in the halted stated %d", target->state);
                }
        }
        else
@@ -733,66 +752,64 @@ int arm7_9_poll(target_t *target)
        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)
-                       {
-                               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)
-                       {
-                               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;
@@ -801,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);
@@ -839,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]);
@@ -862,7 +883,7 @@ int arm7_9_soft_reset_halt(struct target_s *target)
        int i;
        int retval;
        
-       if ((retval=target->type->halt(target))!=ERROR_OK)
+       if ((retval=target_halt(target))!=ERROR_OK)
                return retval;
        
        for (i=0; i<10; i++)
@@ -878,7 +899,7 @@ int arm7_9_soft_reset_halt(struct target_s *target)
        }
        if (i==10)
        {
-               ERROR("Failed to halt CPU after 1 sec");
+               LOG_ERROR("Failed to halt CPU after 1 sec");
                return ERROR_TARGET_TIMEOUT;
        }
        target->state = TARGET_HALTED;
@@ -897,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);
@@ -918,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++)
@@ -932,65 +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;
-       
-       /* 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 */
-               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");
+               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;
                        
@@ -1002,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
        {
@@ -1011,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;
@@ -1035,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)
@@ -1053,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)
@@ -1070,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;
        }
@@ -1113,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)
@@ -1140,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);
@@ -1185,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
@@ -1251,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;
 }
@@ -1268,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 
@@ -1298,19 +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);
+                                       LOG_ERROR("BUG: dirty register '%s', but no valid data", reg->name);
                                }
                        }
                }
@@ -1346,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]);
                                }
                        }
                        
@@ -1359,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);
                        }
                }
@@ -1373,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;
                        
@@ -1404,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)
@@ -1469,11 +1469,11 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_
        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;
        }
        
@@ -1491,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;
@@ -1509,15 +1509,15 @@ 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));
                        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)
@@ -1528,9 +1528,9 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_
                        }
 
                        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));
+                       LOG_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("set breakpoint at 0x%8.8x", breakpoint->address);
                        arm7_9_set_breakpoint(target, breakpoint);
                }
        }
@@ -1551,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 */
@@ -1579,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;
 }
@@ -1595,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)
@@ -1629,7 +1629,7 @@ int arm7_9_step(struct target_s *target, int current, u32 address, int handle_br
 
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
@@ -1658,8 +1658,8 @@ 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);
@@ -1676,7 +1676,7 @@ int arm7_9_step(struct target_s *target, int current, u32 address, int handle_br
        } else {
                arm7_9_debug_entry(target);
                target_call_event_callbacks(target, TARGET_EVENT_HALTED);
-               DEBUG("target stepped");
+               LOG_DEBUG("target stepped");
        }
        
        if (breakpoint)
@@ -1693,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))
@@ -1731,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;
@@ -1755,6 +1758,10 @@ int arm7_9_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mo
        u32 reg[16];
        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))
@@ -1820,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;
        }
 
@@ -1925,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 = 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");
+               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);
 
@@ -1967,12 +1977,12 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun
        int last_reg = 0;
 
 #ifdef _DEBUG_ARM7_9_
-       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);
 #endif
 
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
@@ -2088,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;
        }
@@ -2097,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 = 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");
+               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);
 
@@ -2119,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;
@@ -2129,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);
 
@@ -2146,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);
                }
                
@@ -2207,18 +2220,18 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe
                }
        }
        
-       target->type->halt(target);
+       target_halt(target);
        
        for (i=0; i<100; i++)
        {
-               target->type->poll(target);
+               target_poll(target);
                if (target->state == TARGET_HALTED)
                        break;
                usleep(1000); /* sleep 1ms */
        }
        if (i == 100)
        {
-               ERROR("bulk write timed out, target not halted");
+               LOG_ERROR("bulk write timed out, target not halted");
                return ERROR_TARGET_TIMEOUT;
        }
        
@@ -2296,7 +2309,7 @@ int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32*
        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)
        {
-               ERROR("error executing arm7_9 crc algorithm");
+               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);
@@ -2313,6 +2326,69 @@ int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32*
        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;
@@ -2379,7 +2455,7 @@ 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");
+               LOG_ERROR("JTAG error while writing to xpsr");
                return retval;
        }
        
@@ -2421,7 +2497,7 @@ 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");
+               LOG_ERROR("JTAG error while writing 8-bit immediate to xpsr");
                return retval;
        }
        
@@ -2470,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");
@@ -2665,17 +2747,15 @@ int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
        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;