]> git.sur5r.net Git - openocd/blobdiff - src/target/arm7_9_common.c
- image.c and fileio.c now uses logging to propagate error strings.
[openocd] / src / target / arm7_9_common.c
index e596d057199cc99ac94dade8c8ee7b55940edd23..dd713b9b9f4b0aaa012f2c294b1f9077e967344a 100644 (file)
@@ -186,17 +186,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 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)
+                       {
+                               ERROR("Unable to set 32 bit software breakpoint at address %08x", 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 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)
+                       {
+                               ERROR("Unable to set thumb software breakpoint at address %08x", breakpoint->address);
+                               return ERROR_OK;
+                       }
                }
                breakpoint->set = 1;
        }
@@ -243,11 +259,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;
        }
@@ -569,7 +593,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;
@@ -580,9 +605,18 @@ int arm7_9_execute_fast_sys_speed(struct target_s *target)
        jtag_add_end_state(TAP_RTI);
        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);
@@ -620,6 +654,9 @@ int arm7_9_handle_target_request(void *priv)
        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)
        {
                /* read DCC control register */
@@ -639,7 +676,7 @@ int arm7_9_handle_target_request(void *priv)
        return ERROR_OK;
 }
 
-enum target_state arm7_9_poll(target_t *target)
+int arm7_9_poll(target_t *target)
 {
        int retval;
        armv4_5_common_t *armv4_5 = target->arch_info;
@@ -655,24 +692,16 @@ enum target_state arm7_9_poll(target_t *target)
        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))
+               if (target->state == TARGET_UNKNOWN)
                {
-                       WARNING("DBGACK set while target was in unknown state. Reset or initialize target before resuming");
                        target->state = TARGET_RUNNING;
+                       WARNING("DBGACK set while target was in unknown state. Reset or initialize target.");
                }
                if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
                {
@@ -690,6 +719,10 @@ enum target_state arm7_9_poll(target_t *target)
                        
                        target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
                }
+               if (target->state != TARGET_HALTED)
+               {
+                       WARNING("DBGACK set, but the target did not end up in the halted stated %d", target->state);
+               }
        }
        else
        {
@@ -697,7 +730,7 @@ enum target_state arm7_9_poll(target_t *target)
                        target->state = TARGET_RUNNING;
        }
        
-       return target->state;
+       return ERROR_OK;
 }
 
 int arm7_9_assert_reset(target_t *target)
@@ -731,7 +764,6 @@ int arm7_9_assert_reset(target_t *target)
                {
                        if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
                        {
-                               WARNING("srst resets test logic, too");
                                retval = jtag_add_reset(1, 1);
                        }
                }
@@ -742,7 +774,6 @@ int arm7_9_assert_reset(target_t *target)
                {
                        if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
                        {
-                               WARNING("srst resets test logic, too");
                                retval = jtag_add_reset(1, 1);
                        }
                        
@@ -1125,8 +1156,8 @@ 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)
                return retval;
@@ -1270,7 +1301,6 @@ int arm7_9_restore_context(target_t *target)
                                else
                                {
                                        ERROR("BUG: dirty register '%s', but no valid data", reg->name);
-                                       exit(-1);
                                }
                        }
                }
@@ -1427,6 +1457,7 @@ 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("-");
        
@@ -1474,14 +1505,21 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_
                                
                        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");
                        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);
                        arm7_9_set_breakpoint(target, breakpoint);
                }
@@ -1577,6 +1615,7 @@ 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)
        {
@@ -1615,22 +1654,25 @@ int arm7_9_step(struct target_s *target, int current, u32 address, int handle_br
        
        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);
+               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;
 
 }
 
@@ -1887,13 +1929,13 @@ int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count
        }
        
        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);
+               return ERROR_TARGET_DATA_ABORT;
        }
 
        if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
@@ -1922,7 +1964,9 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun
        int retval;
        int last_reg = 0;
 
+#ifdef _DEBUG_ARM7_9_
        DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
+#endif
 
        if (target->state != TARGET_HALTED)
        {
@@ -2052,13 +2096,13 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun
        embeddedice_store_reg(dbg_ctrl);
        
        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);
+               return ERROR_TARGET_DATA_ABORT;
        }
 
        if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))