]> git.sur5r.net Git - openocd/blobdiff - src/target/arm11.c
arm_cti: add cti command group
[openocd] / src / target / arm11.c
index 26e8116f64ee400e141c7d0b96504bf6fe6ad13f..13fbd207a2f91d7ee54f5ce9ec49b8c3b6f5ba75 100644 (file)
@@ -19,9 +19,7 @@
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -44,7 +42,7 @@
 
 
 static int arm11_step(struct target *target, int current,
-               uint32_t address, int handle_breakpoints);
+               target_addr_t address, int handle_breakpoints);
 
 
 /** Check and if necessary take control of the system
@@ -363,15 +361,6 @@ static int arm11_arch_state(struct target *target)
        return retval;
 }
 
-/* target request support */
-static int arm11_target_request_data(struct target *target,
-       uint32_t size, uint8_t *buffer)
-{
-       LOG_WARNING("Not implemented: %s", __func__);
-
-       return ERROR_FAIL;
-}
-
 /* target execution control */
 static int arm11_halt(struct target *target)
 {
@@ -401,7 +390,7 @@ static int arm11_halt(struct target *target)
                        break;
 
 
-               long long then = 0;
+               int64_t then = 0;
                if (i == 1000)
                        then = timeval_ms();
                if (i >= 1000) {
@@ -429,16 +418,38 @@ static uint32_t arm11_nextpc(struct arm11_common *arm11, int current, uint32_t a
 {
        void *value = arm11->arm.pc->value;
 
-       if (!current)
-               buf_set_u32(value, 0, 32, address);
-       else
+       /* use the current program counter */
+       if (current)
                address = buf_get_u32(value, 0, 32);
 
+       /* Make sure that the gdb thumb fixup does not
+        * kill the return address
+        */
+       switch (arm11->arm.core_state) {
+               case ARM_STATE_ARM:
+                       address &= 0xFFFFFFFC;
+                       break;
+               case ARM_STATE_THUMB:
+                       /* When the return address is loaded into PC
+                        * bit 0 must be 1 to stay in Thumb state
+                        */
+                       address |= 0x1;
+                       break;
+
+               /* catch-all for JAZELLE and THUMB_EE */
+               default:
+                       break;
+       }
+
+       buf_set_u32(value, 0, 32, address);
+       arm11->arm.pc->dirty = 1;
+       arm11->arm.pc->valid = 1;
+
        return address;
 }
 
 static int arm11_resume(struct target *target, int current,
-       uint32_t address, int handle_breakpoints, int debug_execution)
+       target_addr_t address, int handle_breakpoints, int debug_execution)
 {
        /*        LOG_DEBUG("current %d  address %08x  handle_breakpoints %d  debug_execution %d", */
        /*      current, address, handle_breakpoints, debug_execution); */
@@ -456,7 +467,7 @@ static int arm11_resume(struct target *target, int current,
 
        address = arm11_nextpc(arm11, current, address);
 
-       LOG_DEBUG("RESUME PC %08" PRIx32 "%s", address, !current ? "!" : "");
+       LOG_DEBUG("RESUME PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
 
        /* clear breakpoints/watchpoints and VCR*/
        CHECK_RETVAL(arm11_sc7_clear_vbw(arm11));
@@ -470,7 +481,7 @@ static int arm11_resume(struct target *target, int current,
 
                for (bp = target->breakpoints; bp; bp = bp->next) {
                        if (bp->address == address) {
-                               LOG_DEBUG("must step over %08" PRIx32 "", bp->address);
+                               LOG_DEBUG("must step over %08" TARGET_PRIxADDR "", bp->address);
                                arm11_step(target, 1, 0, 0);
                                break;
                        }
@@ -496,7 +507,7 @@ static int arm11_resume(struct target *target, int current,
 
                        CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));
 
-                       LOG_DEBUG("Add BP %d at %08" PRIx32, brp_num,
+                       LOG_DEBUG("Add BP %d at %08" TARGET_PRIxADDR, brp_num,
                                bp->address);
 
                        brp_num++;
@@ -523,7 +534,7 @@ static int arm11_resume(struct target *target, int current,
                        break;
 
 
-               long long then = 0;
+               int64_t then = 0;
                if (i == 1000)
                        then = timeval_ms();
                if (i >= 1000) {
@@ -546,7 +557,7 @@ static int arm11_resume(struct target *target, int current,
 }
 
 static int arm11_step(struct target *target, int current,
-       uint32_t address, int handle_breakpoints)
+       target_addr_t address, int handle_breakpoints)
 {
        LOG_DEBUG("target->state: %s",
                target_state_name(target));
@@ -560,7 +571,7 @@ static int arm11_step(struct target *target, int current,
 
        address = arm11_nextpc(arm11, current, address);
 
-       LOG_DEBUG("STEP PC %08" PRIx32 "%s", address, !current ? "!" : "");
+       LOG_DEBUG("STEP PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
 
 
        /** \todo TODO: Thumb not supported here */
@@ -572,13 +583,13 @@ static int arm11_step(struct target *target, int current,
        /* skip over BKPT */
        if ((next_instruction & 0xFFF00070) == 0xe1200070) {
                address = arm11_nextpc(arm11, 0, address + 4);
-               LOG_DEBUG("Skipping BKPT %08" PRIx32, address);
+               LOG_DEBUG("Skipping BKPT %08" TARGET_PRIxADDR, address);
        }
        /* skip over Wait for interrupt / Standby
         * mcr  15, 0, r?, cr7, cr0, {4} */
        else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90) {
                address = arm11_nextpc(arm11, 0, address + 4);
-               LOG_DEBUG("Skipping WFI %08" PRIx32, address);
+               LOG_DEBUG("Skipping WFI %08" TARGET_PRIxADDR, address);
        }
        /* ignore B to self */
        else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)
@@ -703,21 +714,32 @@ static int arm11_assert_reset(struct target *target)
 {
        struct arm11_common *arm11 = target_to_arm11(target);
 
-       /* optionally catch reset vector */
-       if (target->reset_halt && !(arm11->vcr & 1))
-               CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1));
-
-       /* Issue some kind of warm reset. */
-       if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
-               target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
-       else if (jtag_get_reset_config() & RESET_HAS_SRST) {
-               /* REVISIT handle "pulls" cases, if there's
-                * hardware that needs them to work.
-                */
-               jtag_add_reset(0, 1);
+       if (!(target_was_examined(target))) {
+               if (jtag_get_reset_config() & RESET_HAS_SRST)
+                       jtag_add_reset(0, 1);
+               else {
+                       LOG_WARNING("Reset is not asserted because the target is not examined.");
+                       LOG_WARNING("Use a reset button or power cycle the target.");
+                       return ERROR_TARGET_NOT_EXAMINED;
+               }
        } else {
-               LOG_ERROR("%s: how to reset?", target_name(target));
-               return ERROR_FAIL;
+
+               /* optionally catch reset vector */
+               if (target->reset_halt && !(arm11->vcr & 1))
+                       CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1));
+
+               /* Issue some kind of warm reset. */
+               if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
+                       target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
+               else if (jtag_get_reset_config() & RESET_HAS_SRST) {
+                       /* REVISIT handle "pulls" cases, if there's
+                        * hardware that needs them to work.
+                        */
+                       jtag_add_reset(0, 1);
+               } else {
+                       LOG_ERROR("%s: how to reset?", target_name(target));
+                       return ERROR_FAIL;
+               }
        }
 
        /* registers are now invalid */
@@ -771,13 +793,6 @@ static int arm11_deassert_reset(struct target *target)
        return ERROR_OK;
 }
 
-static int arm11_soft_reset_halt(struct target *target)
-{
-       LOG_WARNING("Not implemented: %s", __func__);
-
-       return ERROR_FAIL;
-}
-
 /* target memory access
  * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
  * count: number of items of <size>
@@ -872,7 +887,7 @@ static int arm11_read_memory_inner(struct target *target,
 }
 
 static int arm11_read_memory(struct target *target,
-       uint32_t address,
+       target_addr_t address,
        uint32_t size,
        uint32_t count,
        uint8_t *buffer)
@@ -1028,7 +1043,7 @@ static int arm11_write_memory_inner(struct target *target,
 }
 
 static int arm11_write_memory(struct target *target,
-       uint32_t address, uint32_t size,
+       target_addr_t address, uint32_t size,
        uint32_t count, const uint8_t *buffer)
 {
        /* pointer increment matters only for multi-unit writes ...
@@ -1094,6 +1109,7 @@ static int arm11_target_create(struct target *target, Jim_Interp *interp)
        if (!arm11)
                return ERROR_FAIL;
 
+       arm11->arm.core_type = ARM_MODE_ANY;
        arm_init_arch_info(target, &arm11->arm);
 
        arm11->jtag_info.tap = target->tap;
@@ -1192,6 +1208,12 @@ static int arm11_examine(struct target *target)
        LOG_DEBUG("IDCODE %08" PRIx32 " IMPLEMENTOR %02x DIDR %08" PRIx32,
                device_id, implementor, didr);
 
+       /* Build register cache "late", after target_init(), since we
+        * want to know if this core supports Secure Monitor mode.
+        */
+       if (!target_was_examined(target))
+               CHECK_RETVAL(arm11_dpm_init(arm11, didr));
+
        /* as a side-effect this reads DSCR and thus
         * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag
         * as suggested by the spec.
@@ -1201,12 +1223,6 @@ static int arm11_examine(struct target *target)
        if (retval != ERROR_OK)
                return retval;
 
-       /* Build register cache "late", after target_init(), since we
-        * want to know if this core supports Secure Monitor mode.
-        */
-       if (!target_was_examined(target))
-               CHECK_RETVAL(arm11_dpm_init(arm11, didr));
-
        /* ETM on ARM11 still uses original scanchain 6 access mode */
        if (arm11->arm.etm && !target_was_examined(target)) {
                *register_get_last_cache_p(&target->reg_cache) =
@@ -1339,15 +1355,12 @@ struct target_type arm11_target = {
        .poll = arm11_poll,
        .arch_state = arm11_arch_state,
 
-       .target_request_data = arm11_target_request_data,
-
        .halt = arm11_halt,
        .resume = arm11_resume,
        .step = arm11_step,
 
        .assert_reset = arm11_assert_reset,
        .deassert_reset = arm11_deassert_reset,
-       .soft_reset_halt = arm11_soft_reset_halt,
 
        .get_gdb_reg_list = arm_get_gdb_reg_list,