- added jlink support, based on Jürgen Stuber patch
[fw/openocd] / src / target / arm7_9_common.c
index 4b393cc2b0fb8f583332f95b5c01099cf5513ac7..61484cccdf9aa4ffae4d3201d378db1916c455da 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)
@@ -519,13 +509,13 @@ int arm7_9_enable_sw_bkpts(struct target_s *target)
        else
        {
                LOG_ERROR("BUG: both watchpoints used, but wp_available >= 1");
-               exit(-1);
+               return ERROR_FAIL;
        }
        
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
                LOG_ERROR("error writing EmbeddedICE registers to enable sw breakpoints");
-               exit(-1);
+               return ERROR_FAIL;
        };
        
        return ERROR_OK;
@@ -649,11 +639,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 +676,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,7 +685,7 @@ int arm7_9_poll(target_t *target)
        
        if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1))
        {
-               LOG_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;
@@ -733,64 +721,63 @@ 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;
-       
+       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_mode == RESET_HALT) || (target->reset_mode == RESET_INIT))
+       {
+               /*
+                * 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)
-                       {
-                               return retval;
-                       }
-                       else
-                       {
-                               LOG_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_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);
                }
        }
-       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)
-                       {
-                               return retval;
-                       }
-                       else if (retval != ERROR_OK)
-                       {
-                               LOG_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;
@@ -860,7 +847,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++)
@@ -930,35 +917,6 @@ 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;
@@ -969,7 +927,7 @@ int arm7_9_halt(target_t *target)
        
        if (target->state == TARGET_HALTED)
        {
-               LOG_WARNING("target was already halted");
+               LOG_DEBUG("target was already halted");
                return ERROR_OK;
        }
        
@@ -1051,15 +1009,7 @@ int arm7_9_debug_entry(target_t *target)
        
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               switch (retval)
-               {
-                       case ERROR_JTAG_QUEUE_FAILED:
-                               LOG_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)
@@ -1249,8 +1199,7 @@ int arm7_9_full_context(target_t *target)
        
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
-               LOG_ERROR("JTAG failure");
-               exit(-1);
+               return retval;
        }
        return ERROR_OK;
 }
@@ -1405,12 +1354,7 @@ int arm7_9_restart_core(struct target_s *target)
        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)
@@ -1508,7 +1452,7 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_
                        else
                        {
                                LOG_ERROR("unhandled core state");
-                               exit(-1);
+                               return ERROR_FAIL;
                        }
                                
                        buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
@@ -1550,7 +1494,7 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_
        else
        {
                LOG_ERROR("unhandled core state");
-               exit(-1);
+               return ERROR_FAIL;
        }
        
        /* deassert DBGACK and INTDIS */
@@ -1657,7 +1601,7 @@ int arm7_9_step(struct target_s *target, int current, u32 address, int handle_br
        else
        {
                LOG_ERROR("unhandled core state");
-               exit(-1);
+               return ERROR_FAIL;
        }
        
        target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
@@ -1729,8 +1673,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)
        {
-               LOG_ERROR("JTAG failure");
-               exit(-1);
+               return retval;
        }
                
        ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
@@ -2117,6 +2060,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;
@@ -2127,12 +2076,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);
 
@@ -2205,11 +2148,11 @@ 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 */
@@ -2468,6 +2411,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");
@@ -2663,16 +2612,12 @@ 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;
 
        armv4_5->arch_info = arm7_9;
        armv4_5->read_core_reg = arm7_9_read_core_reg;