adi_v5: search for Debug and Memory AP support 09/909/6
authorEvan Hunter <ehunter@broadcom.com>
Thu, 11 Oct 2012 22:07:45 +0000 (09:07 +1100)
committerSpencer Oliver <spen@spen-soft.co.uk>
Fri, 15 Mar 2013 15:53:36 +0000 (15:53 +0000)
Adds dap_find_ap() function.

Change-Id: I6643025624009b12d4936de67a605da52c07be49
Signed-off-by: Evan Hunter <ehunter@broadcom.com>
Reviewed-on: http://openocd.zylin.com/909
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
src/target/arm_adi_v5.c
src/target/arm_adi_v5.h
src/target/armv7a.h
src/target/cortex_a.c

index b17fd410f353453b01519672382bf0040cec3776..1572861dc2c2157ad630d3cbcbd033eb9acaff2f 100644 (file)
@@ -1221,6 +1221,60 @@ static bool is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t
                        && ((cid1 & 0x0f) == 0) && cid0 == 0x0d;
 }
 
+/*
+ * This function checks the ID for each access port to find the requested Access Port type
+ */
+int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, uint8_t *ap_num_out)
+{
+       int ap;
+
+       /* Maximum AP number is 255 since the SELECT register is 8 bits */
+       for (ap = 0; ap <= 255; ap++) {
+
+               /* read the IDR register of the Access Port */
+               uint32_t id_val = 0;
+               dap_ap_select(dap, ap);
+
+               int retval = dap_queue_ap_read(dap, AP_REG_IDR, &id_val);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               retval = dap_run(dap);
+
+               /* IDR bits:
+                * 31-28 : Revision
+                * 27-24 : JEDEC bank (0x4 for ARM)
+                * 23-17 : JEDEC code (0x3B for ARM)
+                * 16    : Mem-AP
+                * 15-8  : Reserved
+                *  7-0  : AP Identity (1=AHB-AP 2=APB-AP 0x10=JTAG-AP)
+                */
+
+               /* Reading register for a non-existant AP should not cause an error,
+                * but just to be sure, try to continue searching if an error does happen.
+                */
+               if ((retval == ERROR_OK) &&                  /* Register read success */
+                       ((id_val & 0x0FFF0000) == 0x04770000) && /* Jedec codes match */
+                       ((id_val & 0xFF) == type_to_find)) {     /* type matches*/
+
+                       LOG_DEBUG("Found %s at AP index: %d (IDR=0x%08X)",
+                                               (type_to_find == AP_TYPE_AHB_AP)  ? "AHB-AP"  :
+                                               (type_to_find == AP_TYPE_APB_AP)  ? "APB-AP"  :
+                                               (type_to_find == AP_TYPE_JTAG_AP) ? "JTAG-AP" : "Unknown",
+                                               ap, id_val);
+
+                       *ap_num_out = ap;
+                       return ERROR_OK;
+               }
+       }
+
+       LOG_DEBUG("No %s found",
+                               (type_to_find == AP_TYPE_AHB_AP)  ? "AHB-AP"  :
+                               (type_to_find == AP_TYPE_APB_AP)  ? "APB-AP"  :
+                               (type_to_find == AP_TYPE_JTAG_AP) ? "JTAG-AP" : "Unknown");
+       return ERROR_FAIL;
+}
+
 int dap_get_debugbase(struct adiv5_dap *dap, int ap,
                        uint32_t *out_dbgbase, uint32_t *out_apid)
 {
index bab3292a17f3a88878e4ac09ef35d7305fedc9a9..7f1ebf5ef25775e5d157e949ee09e0ad9d3a074e 100644 (file)
@@ -224,6 +224,15 @@ struct dap_ops {
        int (*run)(struct adiv5_dap *dap);
 };
 
+/*
+ * Access Port types
+ */
+enum ap_type {
+       AP_TYPE_AHB_AP  = 0x01,  /* AHB Memory-AP */
+       AP_TYPE_APB_AP  = 0x02,  /* APB Memory-AP */
+       AP_TYPE_JTAG_AP = 0x10   /* JTAG-AP - JTAG master for controlling other JTAG devices */
+};
+
 /**
  * Queue an IDCODE register read.  This is primarily useful for SWD
  * transports, where it is required as part of link initialization.
@@ -423,6 +432,11 @@ int ahbap_debugport_init(struct adiv5_dap *swjdp);
 int dap_get_debugbase(struct adiv5_dap *dap, int ap,
                        uint32_t *dbgbase, uint32_t *apid);
 
+/* Probe Access Ports to find a particular type */
+int dap_find_ap(struct adiv5_dap *dap,
+                       enum ap_type type_to_find,
+                       uint8_t *ap_num_out);
+
 /* Lookup CoreSight component */
 int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
                        uint32_t dbgbase, uint8_t type, uint32_t *addr);
index 176de53e8563f04e00aea57062f90fea8fec263e..9d6f7c24e1ebd4c85399f6a6bf527b6d88358804 100644 (file)
@@ -99,6 +99,7 @@ struct armv7a_common {
        uint32_t debug_base;
        uint8_t debug_ap;
        uint8_t memory_ap;
+       bool memory_ap_available;
        /* mdir */
        uint8_t multi_processor_system;
        uint8_t cluster_id;
index cc1552d61a43c0889107cd1dc9669c4d04964f03..27b780e6720fadfdaf5f39a90074df5e94f0e2bb 100644 (file)
@@ -70,14 +70,6 @@ static int cortex_a8_virt2phys(struct target *target,
 static int cortex_a8_read_apb_ab_memory(struct target *target,
        uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
 
-/*
- * FIXME do topology discovery using the ROM; don't
- * assume this is an OMAP3.   Also, allow for multiple ARMv7-A
- * cores, with different AP numbering ... don't use a #define
- * for these numbers, use per-core armv7a state.
- */
-#define swjdp_memoryap 0
-#define swjdp_debugap 1
 
 /*  restore cp15_control_reg at resume */
 static int cortex_a8_restore_cp15_control_reg(struct target *target)
@@ -178,11 +170,11 @@ static int cortex_a8_init_debug_access(struct target *target)
 
        /* Unlocking the debug registers for modification
         * The debugport might be uninitialised so try twice */
-       retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
        if (retval != ERROR_OK) {
                /* try again */
-               retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap,
+               retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
                if (retval == ERROR_OK)
                        LOG_USER(
@@ -192,7 +184,7 @@ static int cortex_a8_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, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_PRSR, &dummy);
        if (retval != ERROR_OK)
                return retval;
@@ -225,7 +217,7 @@ static int cortex_a8_exec_opcode(struct target *target,
        /* Wait for InstrCompl bit to be set */
        long long then = timeval_ms();
        while ((dscr & DSCR_INSTR_COMP) == 0) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                if (retval != ERROR_OK) {
                        LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32, opcode);
@@ -237,14 +229,14 @@ static int cortex_a8_exec_opcode(struct target *target,
                }
        }
 
-       retval = mem_ap_sel_write_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_write_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_ITR, opcode);
        if (retval != ERROR_OK)
                return retval;
 
        then = timeval_ms();
        do {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                if (retval != ERROR_OK) {
                        LOG_ERROR("Could not read DSCR register");
@@ -283,7 +275,7 @@ static int cortex_a8_read_regs_through_mem(struct target *target, uint32_t addre
        if (retval != ERROR_OK)
                return retval;
 
-       retval = mem_ap_sel_read_buf_u32(swjdp, swjdp_memoryap,
+       retval = mem_ap_sel_read_buf_u32(swjdp, armv7a->memory_ap,
                        (uint8_t *)(&regfile[1]), 4*15, address);
 
        return retval;
@@ -335,7 +327,7 @@ static int cortex_a8_dap_read_coreregister_u32(struct target *target,
        /* Wait for DTRRXfull then read DTRRTX */
        long long then = timeval_ms();
        while ((dscr & DSCR_DTR_TX_FULL) == 0) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                if (retval != ERROR_OK)
                        return retval;
@@ -345,7 +337,7 @@ static int cortex_a8_dap_read_coreregister_u32(struct target *target,
                }
        }
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DTRTX, value);
        LOG_DEBUG("read DCC 0x%08" PRIx32, *value);
 
@@ -364,7 +356,7 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target,
        LOG_DEBUG("register %i, value 0x%08" PRIx32, regnum, value);
 
        /* Check that DCCRX is not full */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -382,7 +374,7 @@ static int cortex_a8_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, swjdp_debugap,
+       retval = mem_ap_sel_write_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DTRRX, value);
        if (retval != ERROR_OK)
                return retval;
@@ -440,7 +432,7 @@ static int cortex_a8_dap_write_memap_register_u32(struct target *target,
        struct armv7a_common *armv7a = target_to_armv7a(target);
        struct adiv5_dap *swjdp = armv7a->arm.dap;
 
-       retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap, address, value);
+       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, address, value);
 
        return retval;
 }
@@ -465,7 +457,7 @@ static int cortex_a8_write_dcc(struct cortex_a8_common *a8, uint32_t data)
 {
        LOG_DEBUG("write DCC 0x%08" PRIx32, data);
        return mem_ap_sel_write_u32(a8->armv7a_common.arm.dap,
-                       swjdp_debugap, a8->armv7a_common.debug_base + CPUDBG_DTRRX, data);
+               a8->armv7a_common.debug_ap, a8->armv7a_common.debug_base + CPUDBG_DTRRX, data);
 }
 
 static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data,
@@ -481,7 +473,7 @@ static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data,
        /* Wait for DTRRXfull */
        long long then = timeval_ms();
        while ((dscr & DSCR_DTR_TX_FULL) == 0) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+               retval = mem_ap_sel_read_atomic_u32(swjdp, a8->armv7a_common.debug_ap,
                                a8->armv7a_common.debug_base + CPUDBG_DSCR,
                                &dscr);
                if (retval != ERROR_OK)
@@ -492,7 +484,7 @@ static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data,
                }
        }
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, a8->armv7a_common.debug_ap,
                        a8->armv7a_common.debug_base + CPUDBG_DTRTX, data);
        if (retval != ERROR_OK)
                return retval;
@@ -514,7 +506,7 @@ static int cortex_a8_dpm_prepare(struct arm_dpm *dpm)
        /* set up invariant:  INSTR_COMP is set after ever DPM operation */
        long long then = timeval_ms();
        for (;; ) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+               retval = mem_ap_sel_read_atomic_u32(swjdp, a8->armv7a_common.debug_ap,
                                a8->armv7a_common.debug_base + CPUDBG_DSCR,
                                &dscr);
                if (retval != ERROR_OK)
@@ -802,7 +794,7 @@ static int cortex_a8_poll(struct target *target)
                target_call_event_callbacks(target, TARGET_EVENT_HALTED);
                return retval;
        }
-       retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -864,7 +856,7 @@ static int cortex_a8_halt(struct target *target)
         * 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, swjdp_debugap,
+       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DRCR, DRCR_HALT);
        if (retval != ERROR_OK)
                return retval;
@@ -872,19 +864,19 @@ static int cortex_a8_halt(struct target *target)
        /*
         * enter halting debug mode
         */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, dscr | DSCR_HALT_DBG_MODE);
        if (retval != ERROR_OK)
                return retval;
 
        long long then = timeval_ms();
        for (;; ) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                if (retval != ERROR_OK)
                        return retval;
@@ -1010,7 +1002,7 @@ static int cortex_a8_internal_restart(struct target *target)
         * disable IRQs by default, with optional override...
         */
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -1018,12 +1010,12 @@ static int cortex_a8_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, swjdp_debugap,
+       retval = mem_ap_sel_write_atomic_u32(swjdp, 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, swjdp_debugap,
+       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DRCR, DRCR_RESTART |
                        DRCR_CLEAR_EXCEPTIONS);
        if (retval != ERROR_OK)
@@ -1031,7 +1023,7 @@ static int cortex_a8_internal_restart(struct target *target)
 
        long long then = timeval_ms();
        for (;; ) {
-               retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                if (retval != ERROR_OK)
                        return retval;
@@ -1123,7 +1115,7 @@ static int cortex_a8_debug_entry(struct target *target)
        LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr);
 
        /* REVISIT surely we should not re-read DSCR !! */
-       retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -1135,7 +1127,7 @@ static int cortex_a8_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, swjdp_debugap,
+       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DSCR, dscr);
        if (retval != ERROR_OK)
                return retval;
@@ -1147,7 +1139,7 @@ static int cortex_a8_debug_entry(struct target *target)
        if (target->debug_reason == DBG_REASON_WATCHPOINT) {
                uint32_t wfar;
 
-               retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_WFAR,
                                &wfar);
                if (retval != ERROR_OK)
@@ -2107,21 +2099,21 @@ static int cortex_a8_read_phys_memory(struct target *target,
 
        if (count && buffer) {
 
-               if (apsel == swjdp_memoryap) {
+               if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
 
                        /* read memory through AHB-AP */
 
                        switch (size) {
                                case 4:
-                                       retval = mem_ap_sel_read_buf_u32(swjdp, swjdp_memoryap,
+                                       retval = mem_ap_sel_read_buf_u32(swjdp, armv7a->memory_ap,
                                                buffer, 4 * count, address);
                                        break;
                                case 2:
-                                       retval = mem_ap_sel_read_buf_u16(swjdp, swjdp_memoryap,
+                                       retval = mem_ap_sel_read_buf_u16(swjdp, armv7a->memory_ap,
                                                buffer, 2 * count, address);
                                        break;
                                case 1:
-                                       retval = mem_ap_sel_read_buf_u8(swjdp, swjdp_memoryap,
+                                       retval = mem_ap_sel_read_buf_u8(swjdp, armv7a->memory_ap,
                                                buffer, count, address);
                                        break;
                        }
@@ -2151,7 +2143,7 @@ static int cortex_a8_read_memory(struct target *target, uint32_t address,
        /* cortex_a8 handles unaligned memory access */
        LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address,
                size, count);
-       if (apsel == swjdp_memoryap) {
+       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
                retval = cortex_a8_mmu(target, &enabled);
                if (retval != ERROR_OK)
                        return retval;
@@ -2195,21 +2187,21 @@ static int cortex_a8_write_phys_memory(struct target *target,
 
        if (count && buffer) {
 
-               if (apsel == swjdp_memoryap) {
+               if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
 
                        /* write memory through AHB-AP */
 
                        switch (size) {
                                case 4:
-                                       retval = mem_ap_sel_write_buf_u32(swjdp, swjdp_memoryap,
+                                       retval = mem_ap_sel_write_buf_u32(swjdp, armv7a->memory_ap,
                                                buffer, 4 * count, address);
                                        break;
                                case 2:
-                                       retval = mem_ap_sel_write_buf_u16(swjdp, swjdp_memoryap,
+                                       retval = mem_ap_sel_write_buf_u16(swjdp, armv7a->memory_ap,
                                                buffer, 2 * count, address);
                                        break;
                                case 1:
-                                       retval = mem_ap_sel_write_buf_u8(swjdp, swjdp_memoryap,
+                                       retval = mem_ap_sel_write_buf_u8(swjdp, armv7a->memory_ap,
                                                buffer, count, address);
                                        break;
                        }
@@ -2294,7 +2286,7 @@ static int cortex_a8_write_memory(struct target *target, uint32_t address,
        /* cortex_a8 handles unaligned memory access */
        LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address,
                size, count);
-       if (apsel == swjdp_memoryap) {
+       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
 
                LOG_DEBUG("Writing memory to address 0x%x; size %d; count %d", address, size,
                        count);
@@ -2349,16 +2341,16 @@ static int cortex_a8_handle_target_request(void *priv)
        if (target->state == TARGET_RUNNING) {
                uint32_t request;
                uint32_t dscr;
-               retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
 
                /* check if we have data */
                while ((dscr & DSCR_DTR_TX_FULL) && (retval == ERROR_OK)) {
-                       retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+                       retval = mem_ap_sel_read_atomic_u32(swjdp, 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, swjdp_debugap,
+                               retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                        }
                }
@@ -2387,6 +2379,23 @@ static int cortex_a8_examine_first(struct target *target)
        if (retval != ERROR_OK)
                return retval;
 
+       /* Search for the APB-AB - 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);
+       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;
+       }
+
+
        if (!target->dbgbase_set) {
                uint32_t dbgbase;
                /* Get ROM Table base */
@@ -2402,33 +2411,33 @@ static int cortex_a8_examine_first(struct target *target)
        } else
                armv7a->debug_base = target->dbgbase;
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_CPUID, &cpuid);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, 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, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, 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, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, 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, swjdp_debugap,
+       retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
                        armv7a->debug_base + CPUDBG_DIDR, &didr);
        if (retval != ERROR_OK) {
                LOG_DEBUG("Examine %s failed", "DIDR");
@@ -2571,14 +2580,14 @@ static int cortex_a8_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 (apsel == swjdp_memoryap) {
+       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
                uint32_t ret;
                retval = armv7a_mmu_translate_va(target,
                                virt, &ret);
                if (retval != ERROR_OK)
                        goto done;
                *phys = ret;
-       } else {/*  use this method if swjdp_memoryap not selected
+       } else {/*  use this method if armv7a->memory_ap not selected
                 *  mmu must be enable in order to get a correct translation */
                retval = cortex_a8_mmu_modify(target, 1);
                if (retval != ERROR_OK)

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)