cortex_a/r/m: fix handling of un-examined cores
[fw/openocd] / src / target / cortex_a.c
index 7da57b4980cb09e3377570368b7584a59f1b5a37..256edbca3052eede503670e5858af8212c6bd6b9 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                                      *
@@ -55,6 +53,7 @@
 #include "target_request.h"
 #include "target_type.h"
 #include "arm_opcodes.h"
+#include "arm_semihosting.h"
 #include <helper/time_support.h>
 
 static int cortex_a_poll(struct target *target);
@@ -76,7 +75,7 @@ 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);
-static int cortex_a_read_apb_ab_memory(struct target *target,
+static int cortex_a_read_cpu_memory(struct target *target,
        uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
 
 
@@ -106,6 +105,7 @@ static int cortex_a_restore_cp15_control_reg(struct target *target)
 static int cortex_a_prep_memaccess(struct target *target, int phys_access)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct cortex_a_common *cortex_a = target_to_cortex_a(target);
        int mmu_enabled = 0;
 
        if (phys_access == 0) {
@@ -113,6 +113,12 @@ static int cortex_a_prep_memaccess(struct target *target, int phys_access)
                cortex_a_mmu(target, &mmu_enabled);
                if (mmu_enabled)
                        cortex_a_mmu_modify(target, 1);
+               if (cortex_a->dacrfixup_mode == CORTEX_A_DACRFIXUP_ON) {
+                       /* overwrite DACR to all-manager */
+                       armv7a->arm.mcr(target, 15,
+                                       0, 0, 3, 0,
+                                       0xFFFFFFFF);
+               }
        } else {
                cortex_a_mmu(target, &mmu_enabled);
                if (mmu_enabled)
@@ -129,8 +135,15 @@ static int cortex_a_prep_memaccess(struct target *target, int phys_access)
 static int cortex_a_post_memaccess(struct target *target, int phys_access)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct cortex_a_common *cortex_a = target_to_cortex_a(target);
 
        if (phys_access == 0) {
+               if (cortex_a->dacrfixup_mode == CORTEX_A_DACRFIXUP_ON) {
+                       /* restore */
+                       armv7a->arm.mcr(target, 15,
+                                       0, 0, 3, 0,
+                                       cortex_a->cp15_dacr_reg);
+               }
                dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
        } else {
                int mmu_enabled = 0;
@@ -188,18 +201,17 @@ static int cortex_a_mmu_modify(struct target *target, int enable)
 static int cortex_a8_init_debug_access(struct target *target)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        int retval;
 
        LOG_DEBUG(" ");
 
        /* Unlocking the debug registers for modification
         * The debugport might be uninitialised so try twice */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
        if (retval != ERROR_OK) {
                /* try again */
-               retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
                if (retval == ERROR_OK)
                        LOG_USER(
@@ -215,7 +227,6 @@ static int cortex_a8_init_debug_access(struct target *target)
 static int cortex_a_init_debug_access(struct target *target)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        int retval;
        uint32_t dbg_osreg;
        uint32_t cortex_part_num;
@@ -228,7 +239,7 @@ static int cortex_a_init_debug_access(struct target *target)
        switch (cortex_part_num) {
        case CORTEX_A7_PARTNUM:
        case CORTEX_A15_PARTNUM:
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                                    armv7a->debug_base + CPUDBG_OSLSR,
                                                    &dbg_osreg);
                if (retval != ERROR_OK)
@@ -238,7 +249,7 @@ static int cortex_a_init_debug_access(struct target *target)
 
                if (dbg_osreg & CPUDBG_OSLAR_LK_MASK)
                        /* Unlocking the DEBUG OS registers for modification */
-                       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+                       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                                                             armv7a->debug_base + CPUDBG_OSLAR,
                                                             0);
                break;
@@ -254,7 +265,7 @@ static int cortex_a_init_debug_access(struct target *target)
                return retval;
        /* Clear Sticky Power Down status Bit in PRSR to enable access to
           the registers in the Core Power Domain */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       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);
 
@@ -262,13 +273,13 @@ static int cortex_a_init_debug_access(struct target *target)
                return retval;
 
        /* Disable cacheline fills and force cache write-through in debug state */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_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_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSMCR, 0);
        if (retval != ERROR_OK)
                return retval;
@@ -287,11 +298,10 @@ static int cortex_a_wait_instrcmpl(struct target *target, uint32_t *dscr, bool f
         * Writes final value of DSCR into *dscr. Pass force to force always
         * reading DSCR at least once. */
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        while ((*dscr & DSCR_INSTR_COMP) == 0 || force) {
                force = false;
-               int retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               int retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, dscr);
                if (retval != ERROR_OK) {
                        LOG_ERROR("Could not read DSCR register");
@@ -316,7 +326,6 @@ static int cortex_a_exec_opcode(struct target *target,
        uint32_t dscr;
        int retval;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
 
        dscr = dscr_p ? *dscr_p : 0;
 
@@ -327,14 +336,14 @@ static int cortex_a_exec_opcode(struct target *target,
        if (retval != ERROR_OK)
                return retval;
 
-       retval = mem_ap_sel_write_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_ITR, opcode);
        if (retval != ERROR_OK)
                return retval;
 
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        do {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                if (retval != ERROR_OK) {
                        LOG_ERROR("Could not read DSCR register");
@@ -361,7 +370,6 @@ static int cortex_a_read_regs_through_mem(struct target *target, uint32_t addres
 {
        int retval = ERROR_OK;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
 
        retval = cortex_a_dap_read_coreregister_u32(target, regfile, 0);
        if (retval != ERROR_OK)
@@ -373,7 +381,7 @@ static int cortex_a_read_regs_through_mem(struct target *target, uint32_t addres
        if (retval != ERROR_OK)
                return retval;
 
-       retval = mem_ap_sel_read_buf(swjdp, armv7a->memory_ap,
+       retval = mem_ap_read_buf(armv7a->memory_ap,
                        (uint8_t *)(&regfile[1]), 4, 15, address);
 
        return retval;
@@ -386,7 +394,6 @@ static int cortex_a_dap_read_coreregister_u32(struct target *target,
        uint8_t reg = regnum&0xFF;
        uint32_t dscr = 0;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
 
        if (reg > 17)
                return retval;
@@ -423,9 +430,9 @@ static int cortex_a_dap_read_coreregister_u32(struct target *target,
        }
 
        /* Wait for DTRRXfull then read DTRRTX */
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        while ((dscr & DSCR_DTR_TX_FULL) == 0) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                if (retval != ERROR_OK)
                        return retval;
@@ -435,7 +442,7 @@ static int cortex_a_dap_read_coreregister_u32(struct target *target,
                }
        }
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DTRTX, value);
        LOG_DEBUG("read DCC 0x%08" PRIx32, *value);
 
@@ -449,12 +456,11 @@ static int cortex_a_dap_write_coreregister_u32(struct target *target,
        uint8_t Rd = regnum&0xFF;
        uint32_t dscr;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
 
        LOG_DEBUG("register %i, value 0x%08" PRIx32, regnum, value);
 
        /* Check that DCCRX is not full */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -472,7 +478,7 @@ static int cortex_a_dap_write_coreregister_u32(struct target *target,
 
        /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
        LOG_DEBUG("write DCC 0x%08" PRIx32, value);
-       retval = mem_ap_sel_write_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DTRRX, value);
        if (retval != ERROR_OK)
                return retval;
@@ -528,9 +534,8 @@ static int cortex_a_dap_write_memap_register_u32(struct target *target,
 {
        int retval;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
 
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, address, value);
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap, address, value);
 
        return retval;
 }
@@ -554,14 +559,13 @@ static inline struct cortex_a_common *dpm_to_a(struct arm_dpm *dpm)
 static int cortex_a_write_dcc(struct cortex_a_common *a, uint32_t data)
 {
        LOG_DEBUG("write DCC 0x%08" PRIx32, data);
-       return mem_ap_sel_write_u32(a->armv7a_common.arm.dap,
-               a->armv7a_common.debug_ap, a->armv7a_common.debug_base + CPUDBG_DTRRX, data);
+       return mem_ap_write_u32(a->armv7a_common.debug_ap,
+                       a->armv7a_common.debug_base + CPUDBG_DTRRX, data);
 }
 
 static int cortex_a_read_dcc(struct cortex_a_common *a, uint32_t *data,
        uint32_t *dscr_p)
 {
-       struct adiv5_dap *swjdp = a->armv7a_common.arm.dap;
        uint32_t dscr = DSCR_INSTR_COMP;
        int retval;
 
@@ -569,9 +573,9 @@ static int cortex_a_read_dcc(struct cortex_a_common *a, uint32_t *data,
                dscr = *dscr_p;
 
        /* Wait for DTRRXfull */
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        while ((dscr & DSCR_DTR_TX_FULL) == 0) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, a->armv7a_common.debug_ap,
+               retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,
                                a->armv7a_common.debug_base + CPUDBG_DSCR,
                                &dscr);
                if (retval != ERROR_OK)
@@ -582,7 +586,7 @@ static int cortex_a_read_dcc(struct cortex_a_common *a, uint32_t *data,
                }
        }
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, a->armv7a_common.debug_ap,
+       retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,
                        a->armv7a_common.debug_base + CPUDBG_DTRTX, data);
        if (retval != ERROR_OK)
                return retval;
@@ -597,14 +601,13 @@ static int cortex_a_read_dcc(struct cortex_a_common *a, uint32_t *data,
 static int cortex_a_dpm_prepare(struct arm_dpm *dpm)
 {
        struct cortex_a_common *a = dpm_to_a(dpm);
-       struct adiv5_dap *swjdp = a->armv7a_common.arm.dap;
        uint32_t dscr;
        int retval;
 
        /* set up invariant:  INSTR_COMP is set after ever DPM operation */
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        for (;; ) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, a->armv7a_common.debug_ap,
+               retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,
                                a->armv7a_common.debug_base + CPUDBG_DSCR,
                                &dscr);
                if (retval != ERROR_OK)
@@ -850,7 +853,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;
        }
@@ -878,7 +882,6 @@ static int cortex_a_poll(struct target *target)
        uint32_t dscr;
        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;
        enum target_state prev_target_state = target->state;
        /*  toggle to another core is done by gdb as follow */
        /*  maint packet J core_id */
@@ -892,7 +895,7 @@ static int cortex_a_poll(struct target *target)
                target_call_event_callbacks(target, TARGET_EVENT_HALTED);
                return retval;
        }
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -914,6 +917,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);
                        }
@@ -948,13 +955,12 @@ static int cortex_a_halt(struct target *target)
        int retval = ERROR_OK;
        uint32_t dscr;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
 
        /*
         * Tell the core to be halted by writing DRCR with 0x1
         * and then wait for the core to be halted.
         */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DRCR, DRCR_HALT);
        if (retval != ERROR_OK)
                return retval;
@@ -962,19 +968,19 @@ static int cortex_a_halt(struct target *target)
        /*
         * enter halting debug mode
         */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       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;
 
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        for (;; ) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                if (retval != ERROR_OK)
                        return retval;
@@ -1052,6 +1058,7 @@ static int cortex_a_internal_restore(struct target *target, int current,
        buf_set_u32(arm->pc->value, 0, 32, resume_pc);
        arm->pc->dirty = 1;
        arm->pc->valid = 1;
+
        /* restore dpm_mode at system halt */
        dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
        /* called it now before restoring context because it uses cpu
@@ -1089,7 +1096,6 @@ static int cortex_a_internal_restart(struct target *target)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
        struct arm *arm = &armv7a->arm;
-       struct adiv5_dap *swjdp = arm->dap;
        int retval;
        uint32_t dscr;
        /*
@@ -1100,7 +1106,7 @@ static int cortex_a_internal_restart(struct target *target)
         * disable IRQs by default, with optional override...
         */
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -1108,20 +1114,20 @@ static int cortex_a_internal_restart(struct target *target)
        if ((dscr & DSCR_INSTR_COMP) == 0)
                LOG_ERROR("DSCR InstrCompl must be set before leaving debug!");
 
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, dscr & ~DSCR_ITR_EN);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DRCR, DRCR_RESTART |
                        DRCR_CLEAR_EXCEPTIONS);
        if (retval != ERROR_OK)
                return retval;
 
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        for (;; ) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                if (retval != ERROR_OK)
                        return retval;
@@ -1151,7 +1157,8 @@ static int cortex_a_restore_smp(struct target *target, int handle_breakpoints)
        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);
@@ -1201,19 +1208,18 @@ 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 regfile[16], cpsr, spsr, 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 adiv5_dap *swjdp = armv7a->arm.dap;
        struct reg *reg;
 
        LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a->cpudbg_dscr);
 
        /* REVISIT surely we should not re-read DSCR !! */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -1225,7 +1231,7 @@ static int cortex_a_debug_entry(struct target *target)
 
        /* Enable the ITR execution once we are in debug mode */
        dscr |= DSCR_ITR_EN;
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -1237,7 +1243,7 @@ static int cortex_a_debug_entry(struct target *target)
        if (target->debug_reason == DBG_REASON_WATCHPOINT) {
                uint32_t wfar;
 
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_WFAR,
                                &wfar);
                if (retval != ERROR_OK)
@@ -1251,6 +1257,7 @@ static int cortex_a_debug_entry(struct target *target)
        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);
@@ -1295,6 +1302,17 @@ static int cortex_a_debug_entry(struct target *target)
                reg->dirty = reg->valid;
        }
 
+       /* read Saved PSR */
+       retval = cortex_a_dap_read_coreregister_u32(target, &spsr, 17);
+       /*  store current spsr */
+       if (retval != ERROR_OK)
+               return retval;
+
+       reg = arm->spsr;
+       buf_set_u32(reg->value, 0, 32, spsr);
+       reg->valid = 1;
+       reg->dirty = 0;
+
 #if 0
 /* TODO, Move this */
        uint32_t cp15_control_register, cp15_cacr, cp15_nacr;
@@ -1350,17 +1368,26 @@ static int cortex_a_post_debug_entry(struct target *target)
                (cortex_a->cp15_control_reg & 0x1000U) ? 1 : 0;
        cortex_a->curr_mode = armv7a->arm.core_mode;
 
+       /* switch to SVC mode to read DACR */
+       dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC);
+       armv7a->arm.mrc(target, 15,
+                       0, 0, 3, 0,
+                       &cortex_a->cp15_dacr_reg);
+
+       LOG_DEBUG("cp15_dacr_reg: %8.8" PRIx32,
+                       cortex_a->cp15_dacr_reg);
+
+       dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
        return ERROR_OK;
 }
 
 int cortex_a_set_dscr_bits(struct target *target, unsigned long bit_mask, unsigned long value)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        uint32_t dscr;
 
        /* Read DSCR */
-       int retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       int retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (ERROR_OK != retval)
                return retval;
@@ -1371,7 +1398,7 @@ int cortex_a_set_dscr_bits(struct target *target, unsigned long bit_mask, unsign
        dscr |= value & bit_mask;
 
        /* write new DSCR */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, dscr);
        return retval;
 }
@@ -1433,7 +1460,7 @@ static int cortex_a_step(struct target *target, int current, uint32_t address,
        if (retval != ERROR_OK)
                return retval;
 
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        while (target->state != TARGET_HALTED) {
                retval = cortex_a_poll(target);
                if (retval != ERROR_OK)
@@ -1893,6 +1920,8 @@ static int cortex_a_assert_reset(struct target *target)
 
        /* FIXME when halt is requested, make it work somehow... */
 
+       /* This function can be called in "target not examined" state */
+
        /* Issue some kind of warm reset. */
        if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
                target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
@@ -1900,14 +1929,17 @@ static int cortex_a_assert_reset(struct target *target)
                /* REVISIT handle "pulls" cases, if there's
                 * hardware that needs them to work.
                 */
-               jtag_add_reset(0, 1);
+               if (target->reset_halt)
+                       if (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;
 
@@ -1923,17 +1955,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;
                }
        }
 
@@ -1952,8 +1989,8 @@ static int cortex_a_set_dcc_mode(struct target *target, uint32_t mode, uint32_t
        uint32_t new_dscr = (*dscr & ~DSCR_EXT_DCC_MASK) | mode;
        if (new_dscr != *dscr) {
                struct armv7a_common *armv7a = target_to_armv7a(target);
-               int retval = mem_ap_sel_write_atomic_u32(armv7a->arm.dap,
-                               armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, new_dscr);
+               int retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+                               armv7a->debug_base + CPUDBG_DSCR, new_dscr);
                if (retval == ERROR_OK)
                        *dscr = new_dscr;
                return retval;
@@ -1967,12 +2004,11 @@ static int cortex_a_wait_dscr_bits(struct target *target, uint32_t mask,
 {
        /* Waits until the specified bit(s) of DSCR take on a specified value. */
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        int retval;
 
        while ((*dscr & mask) != value) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, dscr);
                if (retval != ERROR_OK)
                        return retval;
@@ -1989,7 +2025,6 @@ static int cortex_a_read_copro(struct target *target, uint32_t opcode,
 {
        int retval;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
 
        /* Move from coprocessor to R0. */
        retval = cortex_a_exec_opcode(target, opcode, dscr);
@@ -2011,7 +2046,7 @@ static int cortex_a_read_copro(struct target *target, uint32_t opcode,
                return retval;
 
        /* Read the value transferred to DTRTX. */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DTRTX, data);
        if (retval != ERROR_OK)
                return retval;
@@ -2044,10 +2079,9 @@ static int cortex_a_write_copro(struct target *target, uint32_t opcode,
 {
        int retval;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
 
        /* Write the value into DTRRX. */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DTRRX, data);
        if (retval != ERROR_OK)
                return retval;
@@ -2116,20 +2150,19 @@ static int cortex_a_dfsr_to_error_code(uint32_t dfsr)
        }
 }
 
-static int cortex_a_write_apb_ab_memory_slow(struct target *target,
+static int cortex_a_write_cpu_memory_slow(struct target *target,
        uint32_t size, uint32_t count, const uint8_t *buffer, uint32_t *dscr)
 {
        /* Writes count objects of size size from *buffer. Old value of DSCR must
         * be in *dscr; updated to new value. This is slow because it works for
         * non-word-sized objects and (maybe) unaligned accesses. If size == 4 and
-        * the address is aligned, cortex_a_write_apb_ab_memory_fast should be
+        * the address is aligned, cortex_a_write_cpu_memory_fast should be
         * preferred.
         * Preconditions:
         * - Address is in R0.
         * - R0 is marked dirty.
         */
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        struct arm *arm = &armv7a->arm;
        int retval;
 
@@ -2151,7 +2184,7 @@ static int cortex_a_write_apb_ab_memory_slow(struct target *target,
                        data = target_buffer_get_u16(target, buffer);
                else
                        data = target_buffer_get_u32(target, buffer);
-               retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DTRRX, data);
                if (retval != ERROR_OK)
                        return retval;
@@ -2192,7 +2225,7 @@ static int cortex_a_write_apb_ab_memory_slow(struct target *target,
        return ERROR_OK;
 }
 
-static int cortex_a_write_apb_ab_memory_fast(struct target *target,
+static int cortex_a_write_cpu_memory_fast(struct target *target,
        uint32_t count, const uint8_t *buffer, uint32_t *dscr)
 {
        /* Writes count objects of size 4 from *buffer. Old value of DSCR must be
@@ -2203,7 +2236,6 @@ static int cortex_a_write_apb_ab_memory_fast(struct target *target,
         * - R0 is marked dirty.
         */
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        int retval;
 
        /* Switch to fast mode if not already in that mode. */
@@ -2212,28 +2244,27 @@ static int cortex_a_write_apb_ab_memory_fast(struct target *target,
                return retval;
 
        /* Latch STC instruction. */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_ITR, ARMV4_5_STC(0, 1, 0, 1, 14, 5, 0, 4));
        if (retval != ERROR_OK)
                return retval;
 
        /* Transfer all the data and issue all the instructions. */
-       return mem_ap_sel_write_buf_noincr(swjdp, armv7a->debug_ap, buffer,
+       return mem_ap_write_buf_noincr(armv7a->debug_ap, buffer,
                        4, count, armv7a->debug_base + CPUDBG_DTRRX);
 }
 
-static int cortex_a_write_apb_ab_memory(struct target *target,
+static int cortex_a_write_cpu_memory(struct target *target,
        uint32_t address, uint32_t size,
        uint32_t count, const uint8_t *buffer)
 {
-       /* Write memory through APB-AP. */
+       /* Write memory through the CPU. */
        int retval, final_retval;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        struct arm *arm = &armv7a->arm;
        uint32_t dscr, orig_dfar, orig_dfsr, fault_dscr, fault_dfar, fault_dfsr;
 
-       LOG_DEBUG("Writing APB-AP memory address 0x%" PRIx32 " size %"  PRIu32 " count %"  PRIu32,
+       LOG_DEBUG("Writing CPU memory address 0x%" PRIx32 " size %"  PRIu32 " count %"  PRIu32,
                          address, size, count);
        if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
@@ -2244,13 +2275,13 @@ static int cortex_a_write_apb_ab_memory(struct target *target,
                return ERROR_OK;
 
        /* Clear any abort. */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS);
        if (retval != ERROR_OK)
                return retval;
 
        /* Read DSCR. */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -2269,7 +2300,7 @@ static int cortex_a_write_apb_ab_memory(struct target *target,
                goto out;
 
        /* Get the memory address into R0. */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DTRRX, address);
        if (retval != ERROR_OK)
                goto out;
@@ -2279,10 +2310,10 @@ static int cortex_a_write_apb_ab_memory(struct target *target,
 
        if (size == 4 && (address % 4) == 0) {
                /* We are doing a word-aligned transfer, so use fast mode. */
-               retval = cortex_a_write_apb_ab_memory_fast(target, count, buffer, &dscr);
+               retval = cortex_a_write_cpu_memory_fast(target, count, buffer, &dscr);
        } else {
                /* Use slow path. */
-               retval = cortex_a_write_apb_ab_memory_slow(target, size, count, buffer, &dscr);
+               retval = cortex_a_write_cpu_memory_slow(target, size, count, buffer, &dscr);
        }
 
 out:
@@ -2301,7 +2332,7 @@ out:
        /* Wait until DTRRX is empty (according to ARMv7-A/-R architecture manual
         * section C8.4.3, checking InstrCmpl_l is not sufficient; one must also
         * check RXfull_l). Most of the time this will be free because RXfull_l
-        * will be cleared immediately and cached in dscr. However, don’t do this
+        * will be cleared immediately and cached in dscr. However, don't do this
         * if there is fault, because then the instruction might not have completed
         * successfully. */
        if (!(dscr & DSCR_STICKY_ABORT_PRECISE)) {
@@ -2313,7 +2344,7 @@ out:
        /* If there were any sticky abort flags, clear them. */
        if (dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) {
                fault_dscr = dscr;
-               mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+               mem_ap_write_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS);
                dscr &= ~(DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE);
        } else {
@@ -2347,7 +2378,7 @@ out:
        /* If the DCC is nonempty, clear it. */
        if (dscr & DSCR_DTRTX_FULL_LATCHED) {
                uint32_t dummy;
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DTRTX, &dummy);
                if (final_retval == ERROR_OK)
                        final_retval = retval;
@@ -2362,20 +2393,19 @@ out:
        return final_retval;
 }
 
-static int cortex_a_read_apb_ab_memory_slow(struct target *target,
+static int cortex_a_read_cpu_memory_slow(struct target *target,
        uint32_t size, uint32_t count, uint8_t *buffer, uint32_t *dscr)
 {
        /* Reads count objects of size size into *buffer. Old value of DSCR must be
         * in *dscr; updated to new value. This is slow because it works for
         * non-word-sized objects and (maybe) unaligned accesses. If size == 4 and
-        * the address is aligned, cortex_a_read_apb_ab_memory_fast should be
+        * the address is aligned, cortex_a_read_cpu_memory_fast should be
         * preferred.
         * Preconditions:
         * - Address is in R0.
         * - R0 is marked dirty.
         */
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        struct arm *arm = &armv7a->arm;
        int retval;
 
@@ -2420,7 +2450,7 @@ static int cortex_a_read_apb_ab_memory_slow(struct target *target,
                        return retval;
 
                /* Read the value transferred to DTRTX into the buffer. */
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DTRTX, &data);
                if (retval != ERROR_OK)
                        return retval;
@@ -2439,7 +2469,7 @@ static int cortex_a_read_apb_ab_memory_slow(struct target *target,
        return ERROR_OK;
 }
 
-static int cortex_a_read_apb_ab_memory_fast(struct target *target,
+static int cortex_a_read_cpu_memory_fast(struct target *target,
        uint32_t count, uint8_t *buffer, uint32_t *dscr)
 {
        /* Reads count objects of size 4 into *buffer. Old value of DSCR must be in
@@ -2450,7 +2480,6 @@ static int cortex_a_read_apb_ab_memory_fast(struct target *target,
         * - R0 is marked dirty.
         */
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        uint32_t u32;
        int retval;
 
@@ -2473,7 +2502,7 @@ static int cortex_a_read_apb_ab_memory_fast(struct target *target,
                        return retval;
 
                /* Latch LDC instruction. */
-               retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_ITR, ARMV4_5_LDC(0, 1, 0, 1, 14, 5, 0, 4));
                if (retval != ERROR_OK)
                        return retval;
@@ -2484,7 +2513,7 @@ static int cortex_a_read_apb_ab_memory_fast(struct target *target,
                 * memory. The last read of DTRTX in this call reads the second-to-last
                 * word from memory and issues the read instruction for the last word.
                 */
-               retval = mem_ap_sel_read_buf_noincr(swjdp, armv7a->debug_ap, buffer,
+               retval = mem_ap_read_buf_noincr(armv7a->debug_ap, buffer,
                                4, count, armv7a->debug_base + CPUDBG_DTRTX);
                if (retval != ERROR_OK)
                        return retval;
@@ -2518,7 +2547,7 @@ static int cortex_a_read_apb_ab_memory_fast(struct target *target,
 
        /* Read the value transferred to DTRTX into the buffer. This is the last
         * word. */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DTRTX, &u32);
        if (retval != ERROR_OK)
                return retval;
@@ -2527,18 +2556,17 @@ static int cortex_a_read_apb_ab_memory_fast(struct target *target,
        return ERROR_OK;
 }
 
-static int cortex_a_read_apb_ab_memory(struct target *target,
+static int cortex_a_read_cpu_memory(struct target *target,
        uint32_t address, uint32_t size,
        uint32_t count, uint8_t *buffer)
 {
-       /* Read memory through APB-AP. */
+       /* Read memory through the CPU. */
        int retval, final_retval;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        struct arm *arm = &armv7a->arm;
        uint32_t dscr, orig_dfar, orig_dfsr, fault_dscr, fault_dfar, fault_dfsr;
 
-       LOG_DEBUG("Reading APB-AP memory address 0x%" PRIx32 " size %"  PRIu32 " count %"  PRIu32,
+       LOG_DEBUG("Reading CPU memory address 0x%" PRIx32 " size %"  PRIu32 " count %"  PRIu32,
                          address, size, count);
        if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
@@ -2549,13 +2577,13 @@ static int cortex_a_read_apb_ab_memory(struct target *target,
                return ERROR_OK;
 
        /* Clear any abort. */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS);
        if (retval != ERROR_OK)
                return retval;
 
        /* Read DSCR */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -2574,7 +2602,7 @@ static int cortex_a_read_apb_ab_memory(struct target *target,
                goto out;
 
        /* Get the memory address into R0. */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DTRRX, address);
        if (retval != ERROR_OK)
                goto out;
@@ -2584,10 +2612,10 @@ static int cortex_a_read_apb_ab_memory(struct target *target,
 
        if (size == 4 && (address % 4) == 0) {
                /* We are doing a word-aligned transfer, so use fast mode. */
-               retval = cortex_a_read_apb_ab_memory_fast(target, count, buffer, &dscr);
+               retval = cortex_a_read_cpu_memory_fast(target, count, buffer, &dscr);
        } else {
                /* Use slow path. */
-               retval = cortex_a_read_apb_ab_memory_slow(target, size, count, buffer, &dscr);
+               retval = cortex_a_read_cpu_memory_slow(target, size, count, buffer, &dscr);
        }
 
 out:
@@ -2606,7 +2634,7 @@ out:
        /* If there were any sticky abort flags, clear them. */
        if (dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) {
                fault_dscr = dscr;
-               mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+               mem_ap_write_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS);
                dscr &= ~(DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE);
        } else {
@@ -2640,7 +2668,7 @@ out:
        /* If the DCC is nonempty, clear it. */
        if (dscr & DSCR_DTRTX_FULL_LATCHED) {
                uint32_t dummy;
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DTRTX, &dummy);
                if (final_retval == ERROR_OK)
                        final_retval = retval;
@@ -2659,7 +2687,7 @@ 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.
  */
 
@@ -2667,17 +2695,25 @@ static int cortex_a_read_phys_memory(struct target *target,
        uint32_t address, uint32_t size,
        uint32_t count, uint8_t *buffer)
 {
-       int retval = ERROR_COMMAND_SYNTAX_ERROR;
+       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,
                address, size, count);
 
-       if (count && buffer) {
-               /* read memory through APB-AP */
-               cortex_a_prep_memaccess(target, 1);
-               retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
-               cortex_a_post_memaccess(target, 1);
-       }
+       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);
+       cortex_a_post_memaccess(target, 1);
+
        return retval;
 }
 
@@ -2691,7 +2727,7 @@ static int cortex_a_read_memory(struct target *target, uint32_t address,
                size, count);
 
        cortex_a_prep_memaccess(target, 0);
-       retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
+       retval = cortex_a_read_cpu_memory(target, address, size, count, buffer);
        cortex_a_post_memaccess(target, 0);
 
        return retval;
@@ -2707,7 +2743,7 @@ static int cortex_a_read_memory_ahb(struct target *target, uint32_t address,
        struct adiv5_dap *swjdp = armv7a->arm.dap;
        uint8_t apsel = swjdp->apsel;
 
-       if (!armv7a->memory_ap_available || (apsel != armv7a->memory_ap))
+       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 */
@@ -2735,7 +2771,7 @@ static int cortex_a_read_memory_ahb(struct target *target, uint32_t address,
        if (!count || !buffer)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       retval = mem_ap_sel_read_buf(swjdp, armv7a->memory_ap, buffer, size, count, address);
+       retval = mem_ap_read_buf(armv7a->memory_ap, buffer, size, count, address);
 
        return retval;
 }
@@ -2744,17 +2780,24 @@ static int cortex_a_write_phys_memory(struct target *target,
        uint32_t address, uint32_t size,
        uint32_t count, const uint8_t *buffer)
 {
-       int retval = ERROR_COMMAND_SYNTAX_ERROR;
+       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 (count && buffer) {
-               /* write memory through APB-AP */
-               cortex_a_prep_memaccess(target, 1);
-               retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
-               cortex_a_post_memaccess(target, 1);
-       }
+       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num))
+               return mem_ap_write_buf(armv7a->memory_ap, buffer, size, count, address);
+
+       /* write memory through the CPU */
+       cortex_a_prep_memaccess(target, 1);
+       retval = cortex_a_write_cpu_memory(target, address, size, count, buffer);
+       cortex_a_post_memaccess(target, 1);
 
        return retval;
 }
@@ -2772,7 +2815,7 @@ static int cortex_a_write_memory(struct target *target, uint32_t address,
        armv7a_cache_auto_flush_on_write(target, address, size * count);
 
        cortex_a_prep_memaccess(target, 0);
-       retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
+       retval = cortex_a_write_cpu_memory(target, address, size, count, buffer);
        cortex_a_post_memaccess(target, 0);
        return retval;
 }
@@ -2787,7 +2830,7 @@ static int cortex_a_write_memory_ahb(struct target *target, uint32_t address,
        struct adiv5_dap *swjdp = armv7a->arm.dap;
        uint8_t apsel = swjdp->apsel;
 
-       if (!armv7a->memory_ap_available || (apsel != armv7a->memory_ap))
+       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 */
@@ -2816,7 +2859,7 @@ static int cortex_a_write_memory_ahb(struct target *target, uint32_t address,
        if (!count || !buffer)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       retval = mem_ap_sel_write_buf(swjdp, armv7a->memory_ap, buffer, size, count, address);
+       retval = mem_ap_write_buf(armv7a->memory_ap, buffer, size, count, address);
 
        return retval;
 }
@@ -2893,7 +2936,6 @@ static int cortex_a_handle_target_request(void *priv)
 {
        struct target *target = priv;
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        int retval;
 
        if (!target_was_examined(target))
@@ -2904,18 +2946,23 @@ static int cortex_a_handle_target_request(void *priv)
        if (target->state == TARGET_RUNNING) {
                uint32_t request;
                uint32_t dscr;
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
 
                /* check if we have data */
+               int64_t then = timeval_ms();
                while ((dscr & DSCR_DTR_TX_FULL) && (retval == ERROR_OK)) {
-                       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+                       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                        armv7a->debug_base + CPUDBG_DTRTX, &request);
                        if (retval == ERROR_OK) {
                                target_request(target, request);
-                               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+                               retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                        }
+                       if (timeval_ms() > then + 1000) {
+                               LOG_ERROR("Timeout waiting for dtr tx full");
+                               return ERROR_FAIL;
+                       }
                }
        }
 
@@ -2931,33 +2978,46 @@ 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;
 
-       /* We do one extra read to ensure DAP is configured,
-        * we call ahbap_debugport_init(swjdp) instead
-        */
-       retval = ahbap_debugport_init(swjdp, 0);
-       if (retval != ERROR_OK)
+       retval = dap_dp_init(swjdp);
+       if (retval != ERROR_OK) {
+               LOG_ERROR("Could not initialize the debug port");
                return retval;
+       }
 
-       /* Search for the APB-AB - it is needed for access to debug registers */
+       /* 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);
        if (retval != ERROR_OK) {
                LOG_ERROR("Could not find APB-AP for debug access");
                return retval;
        }
-       /* Search for the AHB-AB */
-       retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7a->memory_ap);
+
+       retval = mem_ap_init(armv7a->debug_ap);
        if (retval != ERROR_OK) {
-               /* AHB-AP not found - use APB-AP */
-               LOG_DEBUG("Could not find AHB-AP - using APB-AP for memory access");
-               armv7a->memory_ap_available = false;
-       } else {
-               armv7a->memory_ap_available = true;
+               LOG_ERROR("Could not initialize the APB-AP");
+               return retval;
        }
 
+       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;
@@ -2966,11 +3026,11 @@ static int cortex_a_examine_first(struct target *target)
                int32_t coreidx = target->coreid;
                LOG_DEBUG("%s's dbgbase is not set, trying to detect using the ROM table",
                          target->cmd_name);
-               retval = dap_get_debugbase(swjdp, 1, &dbgbase, &apid);
+               retval = dap_get_debugbase(armv7a->debug_ap, &dbgbase, &apid);
                if (retval != ERROR_OK)
                        return retval;
                /* Lookup 0x15 -- Processor DAP */
-               retval = dap_lookup_cs_component(swjdp, 1, dbgbase, 0x15,
+               retval = dap_lookup_cs_component(armv7a->debug_ap, dbgbase, 0x15,
                                &armv7a->debug_base, &coreidx);
                if (retval != ERROR_OK) {
                        LOG_ERROR("Can't detect %s's dbgbase from the ROM table; you need to specify it explicitly.",
@@ -2982,33 +3042,33 @@ static int cortex_a_examine_first(struct target *target)
        } else
                armv7a->debug_base = target->dbgbase;
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_CPUID, &cpuid);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       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_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       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_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_TTYPR, &ttypr);
        if (retval != ERROR_OK) {
                LOG_DEBUG("Examine %s failed", "TTYPR");
                return retval;
        }
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DIDR, &didr);
        if (retval != ERROR_OK) {
                LOG_DEBUG("Examine %s failed", "DIDR");
@@ -3029,7 +3089,7 @@ static int cortex_a_examine_first(struct target *target)
        if ((cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> CORTEX_A_MIDR_PARTNUM_SHIFT ==
                CORTEX_A15_PARTNUM) {
 
-               retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                                                     armv7a->debug_base + CPUDBG_OSLAR,
                                                     0);
 
@@ -3041,7 +3101,7 @@ static int cortex_a_examine_first(struct target *target)
        if ((cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> CORTEX_A_MIDR_PARTNUM_SHIFT ==
                CORTEX_A7_PARTNUM) {
 
-               retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+               retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
                                                     armv7a->debug_base + CPUDBG_OSLAR,
                                                     0);
 
@@ -3049,7 +3109,7 @@ static int cortex_a_examine_first(struct target *target)
                        return retval;
 
        }
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+       retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                            armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg);
 
        if (retval != ERROR_OK)
@@ -3086,6 +3146,9 @@ static int cortex_a_examine_first(struct target *target)
 
        LOG_DEBUG("Configured %i hw breakpoints", cortex_a->brp_num);
 
+       /* select debug_ap as default */
+       swjdp->apsel = armv7a->debug_ap->ap_num;
+
        target_set_examined(target);
        return ERROR_OK;
 }
@@ -3131,7 +3194,6 @@ static int cortex_a_init_arch_info(struct target *target,
                tap->dap->tap = tap;
        }
 
-       tap->dap->ap[dap_ap_get_select(tap->dap)].memaccess_tck = 80;
        armv7a->arm.dap = tap->dap;
 
        cortex_a->fast_reg_read = 0;
@@ -3208,7 +3270,7 @@ static int cortex_a_virt2phys(struct target *target,
        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)) {
+       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num)) {
                uint32_t ret;
                retval = armv7a_mmu_translate_va(target,
                                virt, &ret);
@@ -3316,17 +3378,14 @@ COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)
        };
        const Jim_Nvp *n;
 
-       if (target->state != TARGET_HALTED) {
-               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
-               return ERROR_OK;
-       }
-
        if (CMD_ARGC > 0) {
                n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
-               if (n->name == NULL)
+               if (n->name == NULL) {
+                       LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV[0]);
                        return ERROR_COMMAND_SYNTAX_ERROR;
-               cortex_a->isrmasking_mode = n->value;
+               }
 
+               cortex_a->isrmasking_mode = n->value;
        }
 
        n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode);
@@ -3335,6 +3394,32 @@ COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(handle_cortex_a_dacrfixup_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct cortex_a_common *cortex_a = target_to_cortex_a(target);
+
+       static const Jim_Nvp nvp_dacrfixup_modes[] = {
+               { .name = "off", .value = CORTEX_A_DACRFIXUP_OFF },
+               { .name = "on", .value = CORTEX_A_DACRFIXUP_ON },
+               { .name = NULL, .value = -1 },
+       };
+       const Jim_Nvp *n;
+
+       if (CMD_ARGC > 0) {
+               n = Jim_Nvp_name2value_simple(nvp_dacrfixup_modes, CMD_ARGV[0]);
+               if (n->name == NULL)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               cortex_a->dacrfixup_mode = n->value;
+
+       }
+
+       n = Jim_Nvp_value2name_simple(nvp_dacrfixup_modes, cortex_a->dacrfixup_mode);
+       command_print(CMD_CTX, "cortex_a domain access control fixup %s", n->name);
+
+       return ERROR_OK;
+}
+
 static const struct command_registration cortex_a_exec_command_handlers[] = {
        {
                .name = "cache_info",
@@ -3372,11 +3457,18 @@ static const struct command_registration cortex_a_exec_command_handlers[] = {
        {
                .name = "maskisr",
                .handler = handle_cortex_a_mask_interrupts_command,
-               .mode = COMMAND_EXEC,
+               .mode = COMMAND_ANY,
                .help = "mask cortex_a interrupts",
                .usage = "['on'|'off']",
        },
-
+       {
+               .name = "dacrfixup",
+               .handler = handle_cortex_a_dacrfixup_command,
+               .mode = COMMAND_EXEC,
+               .help = "set domain access control (DACR) to all-manager "
+                       "on memory access",
+               .usage = "['on'|'off']",
+       },
 
        COMMAND_REGISTRATION_DONE
 };