target/cortex_a: enable DSCR_HALT_DBG_MODE during examine
[openocd.git] / src / target / cortex_a.c
index a97e594e4d4d8e94722ed7d9b53e3ed1545dc39b..0a55a2006d4a15905118c89f75566579f7bed1b7 100644 (file)
@@ -18,7 +18,7 @@
  *   michel.jaouen@stericsson.com : smp minimum support                    *
  *                                                                         *
  *   Copyright (C) Broadcom 2012                                           *
- *   ehunter@broadcom.com : Cortex R4 support                              *
+ *   ehunter@broadcom.com : Cortex-R4 support                              *
  *                                                                         *
  *   Copyright (C) 2013 Kamal Dasu                                         *
  *   kdasu.kdev@gmail.com                                                  *
@@ -34,9 +34,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.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  *                                                                         *
  *   Cortex-A8(tm) TRM, ARM DDI 0344H                                      *
  *   Cortex-A9(tm) TRM, ARM DDI 0407F                                      *
 #include "breakpoints.h"
 #include "cortex_a.h"
 #include "register.h"
+#include "armv7a_mmu.h"
 #include "target_request.h"
 #include "target_type.h"
 #include "arm_opcodes.h"
+#include "arm_semihosting.h"
+#include "transport/transport.h"
 #include <helper/time_support.h>
 
+#define foreach_smp_target(pos, head) \
+       for (pos = head; (pos != NULL); pos = pos->next)
+
 static int cortex_a_poll(struct target *target);
 static int cortex_a_debug_entry(struct target *target);
 static int cortex_a_restore_context(struct target *target, bool bpwp);
@@ -68,14 +72,10 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target,
        struct breakpoint *breakpoint);
 static int cortex_a_unset_breakpoint(struct target *target,
        struct breakpoint *breakpoint);
-static int cortex_a_dap_read_coreregister_u32(struct target *target,
-       uint32_t *value, int regnum);
-static int cortex_a_dap_write_coreregister_u32(struct target *target,
-       uint32_t value, int regnum);
 static int cortex_a_mmu(struct target *target, int *enabled);
 static int cortex_a_mmu_modify(struct target *target, int enable);
 static int cortex_a_virt2phys(struct target *target,
-       uint32_t virt, uint32_t *phys);
+       target_addr_t virt, target_addr_t *phys);
 static int cortex_a_read_cpu_memory(struct target *target,
        uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
 
@@ -110,7 +110,7 @@ static int cortex_a_prep_memaccess(struct target *target, int phys_access)
        int mmu_enabled = 0;
 
        if (phys_access == 0) {
-               dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC);
+               arm_dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC);
                cortex_a_mmu(target, &mmu_enabled);
                if (mmu_enabled)
                        cortex_a_mmu_modify(target, 1);
@@ -145,7 +145,7 @@ static int cortex_a_post_memaccess(struct target *target, int phys_access)
                                        0, 0, 3, 0,
                                        cortex_a->cp15_dacr_reg);
                }
-               dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
+               arm_dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
        } else {
                int mmu_enabled = 0;
                cortex_a_mmu(target, &mmu_enabled);
@@ -196,99 +196,52 @@ static int cortex_a_mmu_modify(struct target *target, int enable)
        return retval;
 }
 
-/*
- * Cortex-A Basic debug access, very low level assumes state is saved
- */
-static int cortex_a8_init_debug_access(struct target *target)
-{
-       struct armv7a_common *armv7a = target_to_armv7a(target);
-       int retval;
-
-       LOG_DEBUG(" ");
-
-       /* Unlocking the debug registers for modification
-        * The debugport might be uninitialised so try twice */
-       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
-       if (retval != ERROR_OK) {
-               /* try again */
-               retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
-                               armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
-               if (retval == ERROR_OK)
-                       LOG_USER(
-                               "Locking debug access failed on first, but succeeded on second try.");
-       }
-
-       return retval;
-}
-
 /*
  * Cortex-A Basic debug access, very low level assumes state is saved
  */
 static int cortex_a_init_debug_access(struct target *target)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
+       uint32_t dscr;
        int retval;
-       uint32_t dbg_osreg;
-       uint32_t cortex_part_num;
-       struct cortex_a_common *cortex_a = target_to_cortex_a(target);
-
-       LOG_DEBUG(" ");
-       cortex_part_num = (cortex_a->cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >>
-               CORTEX_A_MIDR_PARTNUM_SHIFT;
-
-       switch (cortex_part_num) {
-       case CORTEX_A7_PARTNUM:
-       case CORTEX_A15_PARTNUM:
-               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                                                   armv7a->debug_base + CPUDBG_OSLSR,
-                                                   &dbg_osreg);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               LOG_DEBUG("DBGOSLSR  0x%" PRIx32, dbg_osreg);
-
-               if (dbg_osreg & CPUDBG_OSLAR_LK_MASK)
-                       /* Unlocking the DEBUG OS registers for modification */
-                       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
-                                                            armv7a->debug_base + CPUDBG_OSLAR,
-                                                            0);
-               break;
-
-       case CORTEX_A5_PARTNUM:
-       case CORTEX_A8_PARTNUM:
-       case CORTEX_A9_PARTNUM:
-       default:
-               retval = cortex_a8_init_debug_access(target);
-       }
-
-       if (retval != ERROR_OK)
-               return retval;
-       /* Clear Sticky Power Down status Bit in PRSR to enable access to
-          the registers in the Core Power Domain */
-       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg);
-       LOG_DEBUG("target->coreid %" PRId32 " DBGPRSR  0x%" PRIx32, target->coreid, dbg_osreg);
 
+       /* lock memory-mapped access to debug registers to prevent
+        * software interference */
+       retval = mem_ap_write_u32(armv7a->debug_ap,
+                       armv7a->debug_base + CPUDBG_LOCKACCESS, 0);
        if (retval != ERROR_OK)
                return retval;
 
        /* Disable cacheline fills and force cache write-through in debug state */
-       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+       retval = mem_ap_write_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCCR, 0);
        if (retval != ERROR_OK)
                return retval;
 
        /* Disable TLB lookup and refill/eviction in debug state */
-       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+       retval = mem_ap_write_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSMCR, 0);
        if (retval != ERROR_OK)
                return retval;
 
+       retval = dap_run(armv7a->debug_ap->dap);
+       if (retval != ERROR_OK)
+               return retval;
+
        /* Enabling of instruction execution in debug mode is done in debug_entry code */
 
        /* Resync breakpoint registers */
 
+       /* Enable halt for breakpoint, watchpoint and vector catch */
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
+                       armv7a->debug_base + CPUDBG_DSCR, &dscr);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+                       armv7a->debug_base + CPUDBG_DSCR, dscr | DSCR_HALT_DBG_MODE);
+       if (retval != ERROR_OK)
+               return retval;
+
        /* Since this is likely called from init or reset, update target state information*/
        return cortex_a_poll(target);
 }
@@ -362,172 +315,6 @@ static int cortex_a_exec_opcode(struct target *target,
        return retval;
 }
 
-/**************************************************************************
-Read core register with very few exec_opcode, fast but needs work_area.
-This can cause problems with MMU active.
-**************************************************************************/
-static int cortex_a_read_regs_through_mem(struct target *target, uint32_t address,
-       uint32_t *regfile)
-{
-       int retval = ERROR_OK;
-       struct armv7a_common *armv7a = target_to_armv7a(target);
-
-       retval = cortex_a_dap_read_coreregister_u32(target, regfile, 0);
-       if (retval != ERROR_OK)
-               return retval;
-       retval = cortex_a_dap_write_coreregister_u32(target, address, 0);
-       if (retval != ERROR_OK)
-               return retval;
-       retval = cortex_a_exec_opcode(target, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = mem_ap_read_buf(armv7a->memory_ap,
-                       (uint8_t *)(&regfile[1]), 4, 15, address);
-
-       return retval;
-}
-
-static int cortex_a_dap_read_coreregister_u32(struct target *target,
-       uint32_t *value, int regnum)
-{
-       int retval = ERROR_OK;
-       uint8_t reg = regnum&0xFF;
-       uint32_t dscr = 0;
-       struct armv7a_common *armv7a = target_to_armv7a(target);
-
-       if (reg > 17)
-               return retval;
-
-       if (reg < 15) {
-               /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0"  0xEE00nE15 */
-               retval = cortex_a_exec_opcode(target,
-                               ARMV4_5_MCR(14, 0, reg, 0, 5, 0),
-                               &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-       } else if (reg == 15) {
-               /* "MOV r0, r15"; then move r0 to DCCTX */
-               retval = cortex_a_exec_opcode(target, 0xE1A0000F, &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-               retval = cortex_a_exec_opcode(target,
-                               ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
-                               &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-       } else {
-               /* "MRS r0, CPSR" or "MRS r0, SPSR"
-                * then move r0 to DCCTX
-                */
-               retval = cortex_a_exec_opcode(target, ARMV4_5_MRS(0, reg & 1), &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-               retval = cortex_a_exec_opcode(target,
-                               ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
-                               &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-
-       /* Wait for DTRRXfull then read DTRRTX */
-       int64_t then = timeval_ms();
-       while ((dscr & DSCR_DTR_TX_FULL) == 0) {
-               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                               armv7a->debug_base + CPUDBG_DSCR, &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-               if (timeval_ms() > then + 1000) {
-                       LOG_ERROR("Timeout waiting for cortex_a_exec_opcode");
-                       return ERROR_FAIL;
-               }
-       }
-
-       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_DTRTX, value);
-       LOG_DEBUG("read DCC 0x%08" PRIx32, *value);
-
-       return retval;
-}
-
-static int cortex_a_dap_write_coreregister_u32(struct target *target,
-       uint32_t value, int regnum)
-{
-       int retval = ERROR_OK;
-       uint8_t Rd = regnum&0xFF;
-       uint32_t dscr;
-       struct armv7a_common *armv7a = target_to_armv7a(target);
-
-       LOG_DEBUG("register %i, value 0x%08" PRIx32, regnum, value);
-
-       /* Check that DCCRX is not full */
-       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_DSCR, &dscr);
-       if (retval != ERROR_OK)
-               return retval;
-       if (dscr & DSCR_DTR_RX_FULL) {
-               LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr);
-               /* Clear DCCRX with MRC(p14, 0, Rd, c0, c5, 0), opcode  0xEE100E15 */
-               retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
-                               &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-
-       if (Rd > 17)
-               return retval;
-
-       /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
-       LOG_DEBUG("write DCC 0x%08" PRIx32, value);
-       retval = mem_ap_write_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_DTRRX, value);
-       if (retval != ERROR_OK)
-               return retval;
-
-       if (Rd < 15) {
-               /* DCCRX to Rn, "MRC p14, 0, Rn, c0, c5, 0", 0xEE10nE15 */
-               retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0),
-                               &dscr);
-
-               if (retval != ERROR_OK)
-                       return retval;
-       } else if (Rd == 15) {
-               /* DCCRX to R0, "MRC p14, 0, R0, c0, c5, 0", 0xEE100E15
-                * then "mov r15, r0"
-                */
-               retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
-                               &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-               retval = cortex_a_exec_opcode(target, 0xE1A0F000, &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-       } else {
-               /* DCCRX to R0, "MRC p14, 0, R0, c0, c5, 0", 0xEE100E15
-                * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
-                */
-               retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
-                               &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-               retval = cortex_a_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, Rd & 1),
-                               &dscr);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               /* "Prefetch flush" after modifying execution status in CPSR */
-               if (Rd == 16) {
-                       retval = cortex_a_exec_opcode(target,
-                                       ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
-                                       &dscr);
-                       if (retval != ERROR_OK)
-                               return retval;
-               }
-       }
-
-       return retval;
-}
-
 /* Write to memory mapped registers directly with no cache or mmu handling */
 static int cortex_a_dap_write_memap_register_u32(struct target *target,
        uint32_t address,
@@ -854,7 +641,8 @@ static int cortex_a_halt_smp(struct target *target)
        head = target->head;
        while (head != (struct target_list *)NULL) {
                curr = head->target;
-               if ((curr != target) && (curr->state != TARGET_HALTED))
+               if ((curr != target) && (curr->state != TARGET_HALTED)
+                       && target_was_examined(curr))
                        retval += cortex_a_halt(curr);
                head = head->next;
        }
@@ -863,12 +651,43 @@ static int cortex_a_halt_smp(struct target *target)
 
 static int update_halt_gdb(struct target *target)
 {
+       struct target *gdb_target = NULL;
+       struct target_list *head;
+       struct target *curr;
        int retval = 0;
+
        if (target->gdb_service && target->gdb_service->core[0] == -1) {
                target->gdb_service->target = target;
                target->gdb_service->core[0] = target->coreid;
                retval += cortex_a_halt_smp(target);
        }
+
+       if (target->gdb_service)
+               gdb_target = target->gdb_service->target;
+
+       foreach_smp_target(head, target->head) {
+               curr = head->target;
+               /* skip calling context */
+               if (curr == target)
+                       continue;
+               if (!target_was_examined(curr))
+                       continue;
+               /* skip targets that were already halted */
+               if (curr->state == TARGET_HALTED)
+                       continue;
+               /* Skip gdb_target; it alerts GDB so has to be polled as last one */
+               if (curr == gdb_target)
+                       continue;
+
+               /* avoid recursion in cortex_a_poll() */
+               curr->smp = 0;
+               cortex_a_poll(curr);
+               curr->smp = 1;
+       }
+
+       /* after all targets were updated, poll the gdb serving target */
+       if (gdb_target != NULL && gdb_target != target)
+               cortex_a_poll(gdb_target);
        return retval;
 }
 
@@ -917,6 +736,10 @@ static int cortex_a_poll(struct target *target)
                                        if (retval != ERROR_OK)
                                                return retval;
                                }
+
+                               if (arm_semihosting(target, &retval) != 0)
+                                       return retval;
+
                                target_call_event_callbacks(target,
                                        TARGET_EVENT_HALTED);
                        }
@@ -936,12 +759,8 @@ static int cortex_a_poll(struct target *target)
                                        TARGET_EVENT_DEBUG_HALTED);
                        }
                }
-       } else if (DSCR_RUN_MODE(dscr) == DSCR_CORE_RESTARTED)
+       } else
                target->state = TARGET_RUNNING;
-       else {
-               LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32, dscr);
-               target->state = TARGET_UNKNOWN;
-       }
 
        return retval;
 }
@@ -961,19 +780,6 @@ static int cortex_a_halt(struct target *target)
        if (retval != ERROR_OK)
                return retval;
 
-       /*
-        * enter halting debug mode
-        */
-       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_DSCR, &dscr);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_DSCR, dscr | DSCR_HALT_DBG_MODE);
-       if (retval != ERROR_OK)
-               return retval;
-
        int64_t then = timeval_ms();
        for (;; ) {
                retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
@@ -994,7 +800,7 @@ static int cortex_a_halt(struct target *target)
 }
 
 static int cortex_a_internal_restore(struct target *target, int current,
-       uint32_t *address, int handle_breakpoints, int debug_execution)
+       target_addr_t *address, int handle_breakpoints, int debug_execution)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
        struct arm *arm = &armv7a->arm;
@@ -1049,6 +855,9 @@ static int cortex_a_internal_restore(struct target *target, int current,
                case ARM_STATE_JAZELLE:
                        LOG_ERROR("How do I resume into Jazelle state??");
                        return ERROR_FAIL;
+               case ARM_STATE_AARCH64:
+                       LOG_ERROR("Shoudn't be in AARCH64 state");
+                       return ERROR_FAIL;
        }
        LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
        buf_set_u32(arm->pc->value, 0, 32, resume_pc);
@@ -1056,7 +865,7 @@ static int cortex_a_internal_restore(struct target *target, int current,
        arm->pc->valid = 1;
 
        /* restore dpm_mode at system halt */
-       dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
+       arm_dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
        /* called it now before restoring context because it uses cpu
         * register r0 for restoring cp15 control register */
        retval = cortex_a_restore_cp15_control_reg(target);
@@ -1149,11 +958,12 @@ static int cortex_a_restore_smp(struct target *target, int handle_breakpoints)
        int retval = 0;
        struct target_list *head;
        struct target *curr;
-       uint32_t address;
+       target_addr_t address;
        head = target->head;
        while (head != (struct target_list *)NULL) {
                curr = head->target;
-               if ((curr != target) && (curr->state != TARGET_RUNNING)) {
+               if ((curr != target) && (curr->state != TARGET_RUNNING)
+                       && target_was_examined(curr)) {
                        /*  resume current address , not in step mode */
                        retval += cortex_a_internal_restore(curr, 1, &address,
                                        handle_breakpoints, 0);
@@ -1166,7 +976,7 @@ static int cortex_a_restore_smp(struct target *target, int handle_breakpoints)
 }
 
 static int cortex_a_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)
 {
        int retval = 0;
        /* dummy resume for smp toggle in order to reduce gdb impact  */
@@ -1190,11 +1000,11 @@ static int cortex_a_resume(struct target *target, int current,
        if (!debug_execution) {
                target->state = TARGET_RUNNING;
                target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
-               LOG_DEBUG("target resumed at 0x%" PRIx32, address);
+               LOG_DEBUG("target resumed at " TARGET_ADDR_FMT, address);
        } else {
                target->state = TARGET_DEBUG_RUNNING;
                target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
-               LOG_DEBUG("target debug resumed at 0x%" PRIx32, address);
+               LOG_DEBUG("target debug resumed at " TARGET_ADDR_FMT, address);
        }
 
        return ERROR_OK;
@@ -1202,14 +1012,11 @@ static int cortex_a_resume(struct target *target, int current,
 
 static int cortex_a_debug_entry(struct target *target)
 {
-       int i;
-       uint32_t regfile[16], cpsr, dscr;
+       uint32_t dscr;
        int retval = ERROR_OK;
-       struct working_area *regfile_working_area = NULL;
        struct cortex_a_common *cortex_a = target_to_cortex_a(target);
        struct armv7a_common *armv7a = target_to_armv7a(target);
        struct arm *arm = &armv7a->arm;
-       struct reg *reg;
 
        LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a->cpudbg_dscr);
 
@@ -1246,54 +1053,16 @@ static int cortex_a_debug_entry(struct target *target)
                arm_dpm_report_wfar(&armv7a->dpm, wfar);
        }
 
-       /* REVISIT fast_reg_read is never set ... */
-
-       /* Examine target state and mode */
-       if (cortex_a->fast_reg_read)
-               target_alloc_working_area(target, 64, &regfile_working_area);
-
-       /* First load register acessible through core debug port*/
-       if (!regfile_working_area)
-               retval = arm_dpm_read_current_registers(&armv7a->dpm);
-       else {
-               retval = cortex_a_read_regs_through_mem(target,
-                               regfile_working_area->address, regfile);
-
-               target_free_working_area(target, regfile_working_area);
-               if (retval != ERROR_OK)
-                       return retval;
+       /* First load register accessible through core debug port */
+       retval = arm_dpm_read_current_registers(&armv7a->dpm);
+       if (retval != ERROR_OK)
+               return retval;
 
-               /* read Current PSR */
-               retval = cortex_a_dap_read_coreregister_u32(target, &cpsr, 16);
-               /*  store current cpsr */
+       if (arm->spsr) {
+               /* read SPSR */
+               retval = arm_dpm_read_reg(&armv7a->dpm, arm->spsr, 17);
                if (retval != ERROR_OK)
                        return retval;
-
-               LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr);
-
-               arm_set_cpsr(arm, cpsr);
-
-               /* update cache */
-               for (i = 0; i <= ARM_PC; i++) {
-                       reg = arm_reg_current(arm, i);
-
-                       buf_set_u32(reg->value, 0, 32, regfile[i]);
-                       reg->valid = 1;
-                       reg->dirty = 0;
-               }
-
-               /* Fixup PC Resume Address */
-               if (cpsr & (1 << 5)) {
-                       /* T bit set for Thumb or ThumbEE state */
-                       regfile[ARM_PC] -= 4;
-               } else {
-                       /* ARM state */
-                       regfile[ARM_PC] -= 8;
-               }
-
-               reg = arm->pc;
-               buf_set_u32(reg->value, 0, 32, regfile[ARM_PC]);
-               reg->dirty = reg->valid;
        }
 
 #if 0
@@ -1336,6 +1105,9 @@ static int cortex_a_post_debug_entry(struct target *target)
        LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a->cp15_control_reg);
        cortex_a->cp15_control_reg_curr = cortex_a->cp15_control_reg;
 
+       if (!armv7a->is_armv7r)
+               armv7a_read_ttbcr(target);
+
        if (armv7a->armv7a_mmu.armv7a_cache.info == -1)
                armv7a_identify_cache(target);
 
@@ -1352,7 +1124,7 @@ static int cortex_a_post_debug_entry(struct target *target)
        cortex_a->curr_mode = armv7a->arm.core_mode;
 
        /* switch to SVC mode to read DACR */
-       dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC);
+       arm_dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC);
        armv7a->arm.mrc(target, 15,
                        0, 0, 3, 0,
                        &cortex_a->cp15_dacr_reg);
@@ -1360,7 +1132,7 @@ static int cortex_a_post_debug_entry(struct target *target)
        LOG_DEBUG("cp15_dacr_reg: %8.8" PRIx32,
                        cortex_a->cp15_dacr_reg);
 
-       dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
+       arm_dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
        return ERROR_OK;
 }
 
@@ -1386,7 +1158,7 @@ int cortex_a_set_dscr_bits(struct target *target, unsigned long bit_mask, unsign
        return retval;
 }
 
-static int cortex_a_step(struct target *target, int current, uint32_t address,
+static int cortex_a_step(struct target *target, int current, target_addr_t address,
        int handle_breakpoints)
 {
        struct cortex_a_common *cortex_a = target_to_cortex_a(target);
@@ -1422,6 +1194,7 @@ static int cortex_a_step(struct target *target, int current, uint32_t address,
 
        /* Setup single step breakpoint */
        stepbreakpoint.address = address;
+       stepbreakpoint.asid = 0;
        stepbreakpoint.length = (arm->core_state == ARM_STATE_THUMB)
                ? 2 : 4;
        stepbreakpoint.type = BKPT_HARD;
@@ -1539,10 +1312,22 @@ static int cortex_a_set_breakpoint(struct target *target,
                        brp_list[brp_i].value);
        } else if (breakpoint->type == BKPT_SOFT) {
                uint8_t code[4];
+               /* length == 2: Thumb breakpoint */
                if (breakpoint->length == 2)
                        buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
                else
+               /* length == 3: Thumb-2 breakpoint, actual encoding is
+                * a regular Thumb BKPT instruction but we replace a
+                * 32bit Thumb-2 instruction, so fix-up the breakpoint
+                * length
+                */
+               if (breakpoint->length == 3) {
+                       buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
+                       breakpoint->length = 4;
+               } else
+                       /* length == 4, normal ARM breakpoint */
                        buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));
+
                retval = target_read_memory(target,
                                breakpoint->address & 0xFFFFFFFE,
                                breakpoint->length, 1,
@@ -1912,16 +1697,23 @@ static int cortex_a_assert_reset(struct target *target)
                /* REVISIT handle "pulls" cases, if there's
                 * hardware that needs them to work.
                 */
-               if (target->reset_halt)
-                       if (jtag_get_reset_config() & RESET_SRST_NO_GATING)
-                               jtag_add_reset(0, 1);
+
+               /*
+                * FIXME: fix reset when transport is SWD. This is a temporary
+                * work-around for release v0.10 that is not intended to stay!
+                */
+               if (transport_is_swd() ||
+                               (target->reset_halt && (jtag_get_reset_config() & RESET_SRST_NO_GATING)))
+                       jtag_add_reset(0, 1);
+
        } else {
                LOG_ERROR("%s: how to reset?", target_name(target));
                return ERROR_FAIL;
        }
 
        /* registers are now invalid */
-       register_cache_invalidate(armv7a->arm.core_cache);
+       if (target_was_examined(target))
+               register_cache_invalidate(armv7a->arm.core_cache);
 
        target->state = TARGET_RESET;
 
@@ -1937,17 +1729,22 @@ static int cortex_a_deassert_reset(struct target *target)
        /* be certain SRST is off */
        jtag_add_reset(0, 0);
 
-       retval = cortex_a_poll(target);
-       if (retval != ERROR_OK)
-               return retval;
+       if (target_was_examined(target)) {
+               retval = cortex_a_poll(target);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
        if (target->reset_halt) {
                if (target->state != TARGET_HALTED) {
                        LOG_WARNING("%s: ran after reset and before halt ...",
                                target_name(target));
-                       retval = target_halt(target);
-                       if (retval != ERROR_OK)
-                               return retval;
+                       if (target_was_examined(target)) {
+                               retval = target_halt(target);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                       } else
+                               target->state = TARGET_UNKNOWN;
                }
        }
 
@@ -2664,28 +2461,22 @@ out:
 /*
  * Cortex-A Memory access
  *
- * This is same Cortex M3 but we must also use the correct
+ * This is same Cortex-M3 but we must also use the correct
  * ap number for every access.
  */
 
 static int cortex_a_read_phys_memory(struct target *target,
-       uint32_t address, uint32_t size,
+       target_addr_t address, uint32_t size,
        uint32_t count, uint8_t *buffer)
 {
-       struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
-       uint8_t apsel = swjdp->apsel;
        int retval;
 
        if (!count || !buffer)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       LOG_DEBUG("Reading memory at real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32,
+       LOG_DEBUG("Reading memory at real address " TARGET_ADDR_FMT "; size %" PRId32 "; count %" PRId32,
                address, size, count);
 
-       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num))
-               return mem_ap_read_buf(armv7a->memory_ap, buffer, size, count, address);
-
        /* read memory through the CPU */
        cortex_a_prep_memaccess(target, 1);
        retval = cortex_a_read_cpu_memory(target, address, size, count, buffer);
@@ -2694,14 +2485,14 @@ static int cortex_a_read_phys_memory(struct target *target,
        return retval;
 }
 
-static int cortex_a_read_memory(struct target *target, uint32_t address,
+static int cortex_a_read_memory(struct target *target, target_addr_t address,
        uint32_t size, uint32_t count, uint8_t *buffer)
 {
        int retval;
 
        /* cortex_a handles unaligned memory access */
-       LOG_DEBUG("Reading memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
-               size, count);
+       LOG_DEBUG("Reading memory at address " TARGET_ADDR_FMT "; size %" PRId32 "; count %" PRId32,
+               address, size, count);
 
        cortex_a_prep_memaccess(target, 0);
        retval = cortex_a_read_cpu_memory(target, address, size, count, buffer);
@@ -2710,66 +2501,17 @@ static int cortex_a_read_memory(struct target *target, uint32_t address,
        return retval;
 }
 
-static int cortex_a_read_memory_ahb(struct target *target, uint32_t address,
-       uint32_t size, uint32_t count, uint8_t *buffer)
-{
-       int mmu_enabled = 0;
-       uint32_t virt, phys;
-       int retval;
-       struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
-       uint8_t apsel = swjdp->apsel;
-
-       if (!armv7a->memory_ap_available || (apsel != armv7a->memory_ap->ap_num))
-               return target_read_memory(target, address, size, count, buffer);
-
-       /* cortex_a handles unaligned memory access */
-       LOG_DEBUG("Reading memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
-               size, count);
-
-       /* determine if MMU was enabled on target stop */
-       if (!armv7a->is_armv7r) {
-               retval = cortex_a_mmu(target, &mmu_enabled);
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-
-       if (mmu_enabled) {
-               virt = address;
-               retval = cortex_a_virt2phys(target, virt, &phys);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               LOG_DEBUG("Reading at virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32,
-                         virt, phys);
-               address = phys;
-       }
-
-       if (!count || !buffer)
-               return ERROR_COMMAND_SYNTAX_ERROR;
-
-       retval = mem_ap_read_buf(armv7a->memory_ap, buffer, size, count, address);
-
-       return retval;
-}
-
 static int cortex_a_write_phys_memory(struct target *target,
-       uint32_t address, uint32_t size,
+       target_addr_t address, uint32_t size,
        uint32_t count, const uint8_t *buffer)
 {
-       struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
-       uint8_t apsel = swjdp->apsel;
        int retval;
 
        if (!count || !buffer)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       LOG_DEBUG("Writing memory to real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
-               size, count);
-
-       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num))
-               return mem_ap_write_buf(armv7a->memory_ap, buffer, size, count, address);
+       LOG_DEBUG("Writing memory to real address " TARGET_ADDR_FMT "; size %" PRId32 "; count %" PRId32,
+               address, size, count);
 
        /* write memory through the CPU */
        cortex_a_prep_memaccess(target, 1);
@@ -2779,14 +2521,14 @@ static int cortex_a_write_phys_memory(struct target *target,
        return retval;
 }
 
-static int cortex_a_write_memory(struct target *target, uint32_t address,
+static int cortex_a_write_memory(struct target *target, target_addr_t address,
        uint32_t size, uint32_t count, const uint8_t *buffer)
 {
        int retval;
 
        /* cortex_a handles unaligned memory access */
-       LOG_DEBUG("Writing memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
-               size, count);
+       LOG_DEBUG("Writing memory at address " TARGET_ADDR_FMT "; size %" PRId32 "; count %" PRId32,
+               address, size, count);
 
        /* memory writes bypass the caches, must flush before writing */
        armv7a_cache_auto_flush_on_write(target, address, size * count);
@@ -2797,51 +2539,7 @@ static int cortex_a_write_memory(struct target *target, uint32_t address,
        return retval;
 }
 
-static int cortex_a_write_memory_ahb(struct target *target, uint32_t address,
-       uint32_t size, uint32_t count, const uint8_t *buffer)
-{
-       int mmu_enabled = 0;
-       uint32_t virt, phys;
-       int retval;
-       struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
-       uint8_t apsel = swjdp->apsel;
-
-       if (!armv7a->memory_ap_available || (apsel != armv7a->memory_ap->ap_num))
-               return target_write_memory(target, address, size, count, buffer);
-
-       /* cortex_a handles unaligned memory access */
-       LOG_DEBUG("Writing memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
-               size, count);
-
-       /* determine if MMU was enabled on target stop */
-       if (!armv7a->is_armv7r) {
-               retval = cortex_a_mmu(target, &mmu_enabled);
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-
-       if (mmu_enabled) {
-               virt = address;
-               retval = cortex_a_virt2phys(target, virt, &phys);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               LOG_DEBUG("Writing to virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32,
-                         virt,
-                         phys);
-               address = phys;
-       }
-
-       if (!count || !buffer)
-               return ERROR_COMMAND_SYNTAX_ERROR;
-
-       retval = mem_ap_write_buf(armv7a->memory_ap, buffer, size, count, address);
-
-       return retval;
-}
-
-static int cortex_a_read_buffer(struct target *target, uint32_t address,
+static int cortex_a_read_buffer(struct target *target, target_addr_t address,
                                uint32_t count, uint8_t *buffer)
 {
        uint32_t size;
@@ -2850,7 +2548,7 @@ static int cortex_a_read_buffer(struct target *target, uint32_t address,
         * will have something to do with the size we leave to it. */
        for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
                if (address & size) {
-                       int retval = cortex_a_read_memory_ahb(target, address, size, 1, buffer);
+                       int retval = target_read_memory(target, address, size, 1, buffer);
                        if (retval != ERROR_OK)
                                return retval;
                        address += size;
@@ -2863,7 +2561,7 @@ static int cortex_a_read_buffer(struct target *target, uint32_t address,
        for (; size > 0; size /= 2) {
                uint32_t aligned = count - count % size;
                if (aligned > 0) {
-                       int retval = cortex_a_read_memory_ahb(target, address, size, aligned / size, buffer);
+                       int retval = target_read_memory(target, address, size, aligned / size, buffer);
                        if (retval != ERROR_OK)
                                return retval;
                        address += aligned;
@@ -2875,7 +2573,7 @@ static int cortex_a_read_buffer(struct target *target, uint32_t address,
        return ERROR_OK;
 }
 
-static int cortex_a_write_buffer(struct target *target, uint32_t address,
+static int cortex_a_write_buffer(struct target *target, target_addr_t address,
                                 uint32_t count, const uint8_t *buffer)
 {
        uint32_t size;
@@ -2884,7 +2582,7 @@ static int cortex_a_write_buffer(struct target *target, uint32_t address,
         * will have something to do with the size we leave to it. */
        for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
                if (address & size) {
-                       int retval = cortex_a_write_memory_ahb(target, address, size, 1, buffer);
+                       int retval = target_write_memory(target, address, size, 1, buffer);
                        if (retval != ERROR_OK)
                                return retval;
                        address += size;
@@ -2897,7 +2595,7 @@ static int cortex_a_write_buffer(struct target *target, uint32_t address,
        for (; size > 0; size /= 2) {
                uint32_t aligned = count - count % size;
                if (aligned > 0) {
-                       int retval = cortex_a_write_memory_ahb(target, address, size, aligned / size, buffer);
+                       int retval = target_write_memory(target, address, size, aligned / size, buffer);
                        if (retval != ERROR_OK)
                                return retval;
                        address += aligned;
@@ -2955,15 +2653,10 @@ static int cortex_a_examine_first(struct target *target)
        struct cortex_a_common *cortex_a = target_to_cortex_a(target);
        struct armv7a_common *armv7a = &cortex_a->armv7a_common;
        struct adiv5_dap *swjdp = armv7a->arm.dap;
+
        int i;
        int retval = ERROR_OK;
-       uint32_t didr, ctypr, ttypr, cpuid, dbg_osreg;
-
-       retval = dap_dp_init(swjdp);
-       if (retval != ERROR_OK) {
-               LOG_ERROR("Could not initialize the debug port");
-               return retval;
-       }
+       uint32_t didr, cpuid, dbg_osreg;
 
        /* Search for the APB-AP - it is needed for access to debug registers */
        retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap);
@@ -2980,21 +2673,6 @@ static int cortex_a_examine_first(struct target *target)
 
        armv7a->debug_ap->memaccess_tck = 80;
 
-       /* Search for the AHB-AB.
-        * REVISIT: We should search for AXI-AP as well and make sure the AP's MEMTYPE says it
-        * can access system memory. */
-       armv7a->memory_ap_available = false;
-       retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7a->memory_ap);
-       if (retval == ERROR_OK) {
-               retval = mem_ap_init(armv7a->memory_ap);
-               if (retval == ERROR_OK)
-                       armv7a->memory_ap_available = true;
-       }
-       if (retval != ERROR_OK) {
-               /* AHB-AP not found or unavailable - use the CPU */
-               LOG_DEBUG("No AHB-AP available for memory access");
-       }
-
        if (!target->dbgbase_set) {
                uint32_t dbgbase;
                /* Get ROM Table base */
@@ -3019,79 +2697,69 @@ static int cortex_a_examine_first(struct target *target)
                armv7a->debug_base = target->dbgbase;
 
        retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_CPUID, &cpuid);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_CPUID, &cpuid);
-       if (retval != ERROR_OK) {
-               LOG_DEBUG("Examine %s failed", "CPUID");
-               return retval;
-       }
-
-       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_CTYPR, &ctypr);
-       if (retval != ERROR_OK) {
-               LOG_DEBUG("Examine %s failed", "CTYPR");
-               return retval;
-       }
-
-       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_TTYPR, &ttypr);
+                       armv7a->debug_base + CPUDBG_DIDR, &didr);
        if (retval != ERROR_OK) {
-               LOG_DEBUG("Examine %s failed", "TTYPR");
+               LOG_DEBUG("Examine %s failed", "DIDR");
                return retval;
        }
 
        retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                       armv7a->debug_base + CPUDBG_DIDR, &didr);
+                       armv7a->debug_base + CPUDBG_CPUID, &cpuid);
        if (retval != ERROR_OK) {
-               LOG_DEBUG("Examine %s failed", "DIDR");
+               LOG_DEBUG("Examine %s failed", "CPUID");
                return retval;
        }
 
-       LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
-       LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr);
-       LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr);
        LOG_DEBUG("didr = 0x%08" PRIx32, didr);
+       LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
 
-       cortex_a->cpuid = cpuid;
-       cortex_a->ctypr = ctypr;
-       cortex_a->ttypr = ttypr;
        cortex_a->didr = didr;
+       cortex_a->cpuid = cpuid;
 
-       /* Unlocking the debug registers */
-       if ((cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> CORTEX_A_MIDR_PARTNUM_SHIFT ==
-               CORTEX_A15_PARTNUM) {
-
-               retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
-                                                    armv7a->debug_base + CPUDBG_OSLAR,
-                                                    0);
-
-               if (retval != ERROR_OK)
-                       return retval;
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
+                                   armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg);
+       if (retval != ERROR_OK)
+               return retval;
+       LOG_DEBUG("target->coreid %" PRId32 " DBGPRSR  0x%" PRIx32, target->coreid, dbg_osreg);
 
+       if ((dbg_osreg & PRSR_POWERUP_STATUS) == 0) {
+               LOG_ERROR("target->coreid %" PRId32 " powered down!", target->coreid);
+               target->state = TARGET_UNKNOWN; /* TARGET_NO_POWER? */
+               return ERROR_TARGET_INIT_FAILED;
        }
-       /* Unlocking the debug registers */
-       if ((cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> CORTEX_A_MIDR_PARTNUM_SHIFT ==
-               CORTEX_A7_PARTNUM) {
-
-               retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
-                                                    armv7a->debug_base + CPUDBG_OSLAR,
-                                                    0);
 
-               if (retval != ERROR_OK)
-                       return retval;
+       if (dbg_osreg & PRSR_STICKY_RESET_STATUS)
+               LOG_DEBUG("target->coreid %" PRId32 " was reset!", target->coreid);
 
-       }
+       /* Read DBGOSLSR and check if OSLK is implemented */
        retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
-                                           armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg);
-
+                               armv7a->debug_base + CPUDBG_OSLSR, &dbg_osreg);
        if (retval != ERROR_OK)
                return retval;
+       LOG_DEBUG("target->coreid %" PRId32 " DBGOSLSR 0x%" PRIx32, target->coreid, dbg_osreg);
 
-       LOG_DEBUG("target->coreid %" PRId32 " DBGPRSR  0x%" PRIx32, target->coreid, dbg_osreg);
+       /* check if OS Lock is implemented */
+       if ((dbg_osreg & OSLSR_OSLM) == OSLSR_OSLM0 || (dbg_osreg & OSLSR_OSLM) == OSLSR_OSLM1) {
+               /* check if OS Lock is set */
+               if (dbg_osreg & OSLSR_OSLK) {
+                       LOG_DEBUG("target->coreid %" PRId32 " OSLock set! Trying to unlock", target->coreid);
+
+                       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+                                                       armv7a->debug_base + CPUDBG_OSLAR,
+                                                       0);
+                       if (retval == ERROR_OK)
+                               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
+                                                       armv7a->debug_base + CPUDBG_OSLSR, &dbg_osreg);
+
+                       /* if we fail to access the register or cannot reset the OSLK bit, bail out */
+                       if (retval != ERROR_OK || (dbg_osreg & OSLSR_OSLK) != 0) {
+                               LOG_ERROR("target->coreid %" PRId32 " OSLock sticky, core not powered?",
+                                               target->coreid);
+                               target->state = TARGET_UNKNOWN; /* TARGET_NO_POWER? */
+                               return ERROR_TARGET_INIT_FAILED;
+                       }
+               }
+       }
 
        armv7a->arm.core_type = ARM_MODE_MON;
 
@@ -3151,28 +2819,18 @@ static int cortex_a_init_target(struct command_context *cmd_ctx,
        struct target *target)
 {
        /* examine_first() does a bunch of this */
+       arm_semihosting_init(target);
        return ERROR_OK;
 }
 
 static int cortex_a_init_arch_info(struct target *target,
-       struct cortex_a_common *cortex_a, struct jtag_tap *tap)
+       struct cortex_a_common *cortex_a, struct adiv5_dap *dap)
 {
        struct armv7a_common *armv7a = &cortex_a->armv7a_common;
 
        /* Setup struct cortex_a_common */
        cortex_a->common_magic = CORTEX_A_COMMON_MAGIC;
-
-       /*  tap has no dap initialized */
-       if (!tap->dap) {
-               tap->dap = dap_init();
-
-               /* Leave (only) generic DAP stuff for debugport_init() */
-               tap->dap->tap = tap;
-       }
-
-       armv7a->arm.dap = tap->dap;
-
-       cortex_a->fast_reg_read = 0;
+       armv7a->arm.dap = dap;
 
        /* register arch-specific functions */
        armv7a->examine_debug_reason = NULL;
@@ -3196,29 +2854,58 @@ static int cortex_a_init_arch_info(struct target *target,
 static int cortex_a_target_create(struct target *target, Jim_Interp *interp)
 {
        struct cortex_a_common *cortex_a = calloc(1, sizeof(struct cortex_a_common));
+       cortex_a->common_magic = CORTEX_A_COMMON_MAGIC;
+       struct adiv5_private_config *pc;
+
+       if (target->private_config == NULL)
+               return ERROR_FAIL;
+
+       pc = (struct adiv5_private_config *)target->private_config;
 
        cortex_a->armv7a_common.is_armv7r = false;
 
-       return cortex_a_init_arch_info(target, cortex_a, target->tap);
+       cortex_a->armv7a_common.arm.arm_vfp_version = ARM_VFP_V3;
+
+       return cortex_a_init_arch_info(target, cortex_a, pc->dap);
 }
 
 static int cortex_r4_target_create(struct target *target, Jim_Interp *interp)
 {
        struct cortex_a_common *cortex_a = calloc(1, sizeof(struct cortex_a_common));
+       cortex_a->common_magic = CORTEX_A_COMMON_MAGIC;
+       struct adiv5_private_config *pc;
+
+       pc = (struct adiv5_private_config *)target->private_config;
+       if (adiv5_verify_config(pc) != ERROR_OK)
+               return ERROR_FAIL;
 
        cortex_a->armv7a_common.is_armv7r = true;
 
-       return cortex_a_init_arch_info(target, cortex_a, target->tap);
+       return cortex_a_init_arch_info(target, cortex_a, pc->dap);
 }
 
 static void cortex_a_deinit_target(struct target *target)
 {
        struct cortex_a_common *cortex_a = target_to_cortex_a(target);
-       struct arm_dpm *dpm = &cortex_a->armv7a_common.dpm;
+       struct armv7a_common *armv7a = &cortex_a->armv7a_common;
+       struct arm_dpm *dpm = &armv7a->dpm;
+       uint32_t dscr;
+       int retval;
+
+       if (target_was_examined(target)) {
+               /* Disable halt for breakpoint, watchpoint and vector catch */
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
+                               armv7a->debug_base + CPUDBG_DSCR, &dscr);
+               if (retval == ERROR_OK)
+                       mem_ap_write_atomic_u32(armv7a->debug_ap,
+                                       armv7a->debug_base + CPUDBG_DSCR,
+                                       dscr & ~DSCR_HALT_DBG_MODE);
+       }
 
        free(cortex_a->brp_list);
        free(dpm->dbp);
        free(dpm->dwp);
+       free(target->private_config);
        free(cortex_a);
 }
 
@@ -3240,28 +2927,29 @@ static int cortex_a_mmu(struct target *target, int *enabled)
 }
 
 static int cortex_a_virt2phys(struct target *target,
-       uint32_t virt, uint32_t *phys)
+       target_addr_t virt, target_addr_t *phys)
 {
-       int retval = ERROR_FAIL;
-       struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
-       uint8_t apsel = swjdp->apsel;
-       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num)) {
-               uint32_t ret;
-               retval = armv7a_mmu_translate_va(target,
-                               virt, &ret);
-               if (retval != ERROR_OK)
-                       goto done;
-               *phys = ret;
-       } else {/*  use this method if armv7a->memory_ap not selected
-                *  mmu must be enable in order to get a correct translation */
-               retval = cortex_a_mmu_modify(target, 1);
-               if (retval != ERROR_OK)
-                       goto done;
-               retval = armv7a_mmu_translate_va_pa(target, virt,  phys, 1);
+       int retval;
+       int mmu_enabled = 0;
+
+       /*
+        * If the MMU was not enabled at debug entry, there is no
+        * way of knowing if there was ever a valid configuration
+        * for it and thus it's not safe to enable it. In this case,
+        * just return the virtual address as physical.
+        */
+       cortex_a_mmu(target, &mmu_enabled);
+       if (!mmu_enabled) {
+               *phys = virt;
+               return ERROR_OK;
        }
-done:
-       return retval;
+
+       /* mmu must be enable in order to get a correct translation */
+       retval = cortex_a_mmu_modify(target, 1);
+       if (retval != ERROR_OK)
+               return retval;
+       return armv7a_mmu_translate_va_pa(target, (uint32_t)virt,
+                                                   (uint32_t *)phys, 1);
 }
 
 COMMAND_HANDLER(cortex_a_handle_cache_info_command)
@@ -3440,11 +3128,14 @@ static const struct command_registration cortex_a_exec_command_handlers[] = {
        {
                .name = "dacrfixup",
                .handler = handle_cortex_a_dacrfixup_command,
-               .mode = COMMAND_EXEC,
+               .mode = COMMAND_ANY,
                .help = "set domain access control (DACR) to all-manager "
                        "on memory access",
                .usage = "['on'|'off']",
        },
+       {
+               .chain = armv7a_mmu_command_handlers,
+       },
 
        COMMAND_REGISTRATION_DONE
 };
@@ -3502,6 +3193,7 @@ struct target_type cortexa_target = {
 
        .commands = cortex_a_command_handlers,
        .target_create = cortex_a_target_create,
+       .target_jim_configure = adiv5_jim_configure,
        .init_target = cortex_a_init_target,
        .examine = cortex_a_examine,
        .deinit_target = cortex_a_deinit_target,
@@ -3513,13 +3205,6 @@ struct target_type cortexa_target = {
 };
 
 static const struct command_registration cortex_r4_exec_command_handlers[] = {
-       {
-               .name = "cache_info",
-               .handler = cortex_a_handle_cache_info_command,
-               .mode = COMMAND_EXEC,
-               .help = "display information about target caches",
-               .usage = "",
-       },
        {
                .name = "dbginit",
                .handler = cortex_a_handle_dbginit_command,
@@ -3541,9 +3226,6 @@ static const struct command_registration cortex_r4_command_handlers[] = {
        {
                .chain = arm_command_handlers,
        },
-       {
-               .chain = armv7a_command_handlers,
-       },
        {
                .name = "cortex_r4",
                .mode = COMMAND_ANY,
@@ -3570,8 +3252,8 @@ struct target_type cortexr4_target = {
        /* REVISIT allow exporting VFP3 registers ... */
        .get_gdb_reg_list = arm_get_gdb_reg_list,
 
-       .read_memory = cortex_a_read_memory,
-       .write_memory = cortex_a_write_memory,
+       .read_memory = cortex_a_read_phys_memory,
+       .write_memory = cortex_a_write_phys_memory,
 
        .checksum_memory = arm_checksum_memory,
        .blank_check_memory = arm_blank_check_memory,
@@ -3587,6 +3269,7 @@ struct target_type cortexr4_target = {
 
        .commands = cortex_r4_command_handlers,
        .target_create = cortex_r4_target_create,
+       .target_jim_configure = adiv5_jim_configure,
        .init_target = cortex_a_init_target,
        .examine = cortex_a_examine,
        .deinit_target = cortex_a_deinit_target,

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)