smp: move sub-command "smp_gdb" in file smp.c
[openocd.git] / src / target / cortex_a.c
index 8985051ee8bbf5fee7088ccb10742abd7eb7bcaa..6eb6aa933836fd6bf510ccc4c422bc4f78d46366 100644 (file)
 #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 "smp.h"
 #include <helper/time_support.h>
 
 static int cortex_a_poll(struct target *target);
@@ -68,10 +70,6 @@ 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,
@@ -110,7 +108,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 +143,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);
@@ -202,6 +200,7 @@ static int cortex_a_mmu_modify(struct target *target, int enable)
 static int cortex_a_init_debug_access(struct target *target)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
+       uint32_t dscr;
        int retval;
 
        /* lock memory-mapped access to debug registers to prevent
@@ -231,6 +230,16 @@ static int cortex_a_init_debug_access(struct target *target)
 
        /* 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);
 }
@@ -304,172 +313,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,
@@ -806,12 +649,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;
 }
 
@@ -849,39 +723,26 @@ static int cortex_a_poll(struct target *target)
                        /* We have a halting debug event */
                        LOG_DEBUG("Target halted");
                        target->state = TARGET_HALTED;
-                       if ((prev_target_state == TARGET_RUNNING)
-                               || (prev_target_state == TARGET_UNKNOWN)
-                               || (prev_target_state == TARGET_RESET)) {
-                               retval = cortex_a_debug_entry(target);
+
+                       retval = cortex_a_debug_entry(target);
+                       if (retval != ERROR_OK)
+                               return retval;
+
+                       if (target->smp) {
+                               retval = update_halt_gdb(target);
                                if (retval != ERROR_OK)
                                        return retval;
-                               if (target->smp) {
-                                       retval = update_halt_gdb(target);
-                                       if (retval != ERROR_OK)
-                                               return retval;
-                               }
+                       }
 
+                       if (prev_target_state == TARGET_DEBUG_RUNNING) {
+                               target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
+                       } else { /* prev_target_state is RUNNING, UNKNOWN or RESET */
                                if (arm_semihosting(target, &retval) != 0)
                                        return retval;
 
                                target_call_event_callbacks(target,
                                        TARGET_EVENT_HALTED);
                        }
-                       if (prev_target_state == TARGET_DEBUG_RUNNING) {
-                               LOG_DEBUG(" ");
-
-                               retval = cortex_a_debug_entry(target);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                               if (target->smp) {
-                                       retval = update_halt_gdb(target);
-                                       if (retval != ERROR_OK)
-                                               return retval;
-                               }
-
-                               target_call_event_callbacks(target,
-                                       TARGET_EVENT_DEBUG_HALTED);
-                       }
                }
        } else
                target->state = TARGET_RUNNING;
@@ -904,19 +765,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,
@@ -956,15 +804,15 @@ static int cortex_a_internal_restore(struct target *target, int current,
                 * C_MASKINTS in parallel with disabled interrupts can cause
                 * local faults to not be taken. */
                buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
-               armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = 1;
-               armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = 1;
+               armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = true;
+               armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = true;
 
                /* Make sure we are in Thumb mode */
                buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
                        buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0,
                        32) | (1 << 24));
-               armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1;
-               armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = 1;
+               armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = true;
+               armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = true;
        }
 #endif
 
@@ -998,11 +846,11 @@ static int cortex_a_internal_restore(struct target *target, int current,
        }
        LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
        buf_set_u32(arm->pc->value, 0, 32, resume_pc);
-       arm->pc->dirty = 1;
-       arm->pc->valid = 1;
+       arm->pc->dirty = true;
+       arm->pc->valid = true;
 
        /* 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,14 +997,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, spsr, 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);
 
@@ -1193,68 +1038,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;
-
-               /* read Current PSR */
-               retval = cortex_a_dap_read_coreregister_u32(target, &cpsr, 16);
-               /*  store current cpsr */
-               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;
-       }
+       /* First load register accessible through core debug port */
+       retval = arm_dpm_read_current_registers(&armv7a->dpm);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (arm->spsr) {
-               /* read Saved PSR */
-               retval = cortex_a_dap_read_coreregister_u32(target, &spsr, 17);
-               /*  store current spsr */
+               /* read SPSR */
+               retval = arm_dpm_read_reg(&armv7a->dpm, arm->spsr, 17);
                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
@@ -1297,6 +1090,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);
 
@@ -1313,7 +1109,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);
@@ -1321,7 +1117,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;
 }
 
@@ -1383,6 +1179,7 @@ static int cortex_a_step(struct target *target, int current, target_addr_t addre
 
        /* Setup single step breakpoint */
        stepbreakpoint.address = address;
+       stepbreakpoint.asid = 0;
        stepbreakpoint.length = (arm->core_state == ARM_STATE_THUMB)
                ? 2 : 4;
        stepbreakpoint.type = BKPT_HARD;
@@ -2657,9 +2454,6 @@ static int cortex_a_read_phys_memory(struct target *target,
        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)
@@ -2668,9 +2462,6 @@ static int cortex_a_read_phys_memory(struct target *target,
        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);
@@ -2695,57 +2486,10 @@ static int cortex_a_read_memory(struct target *target, target_addr_t address,
        return retval;
 }
 
-static int cortex_a_read_memory_ahb(struct target *target, target_addr_t address,
-       uint32_t size, uint32_t count, uint8_t *buffer)
-{
-       int mmu_enabled = 0;
-       target_addr_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 " TARGET_ADDR_FMT "; 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:" TARGET_ADDR_FMT " to r:" TARGET_ADDR_FMT,
-                         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,
        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)
@@ -2754,9 +2498,6 @@ static int cortex_a_write_phys_memory(struct target *target,
        LOG_DEBUG("Writing memory to 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_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);
@@ -2783,51 +2524,6 @@ static int cortex_a_write_memory(struct target *target, target_addr_t address,
        return retval;
 }
 
-static int cortex_a_write_memory_ahb(struct target *target, target_addr_t address,
-       uint32_t size, uint32_t count, const uint8_t *buffer)
-{
-       int mmu_enabled = 0;
-       target_addr_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 " TARGET_ADDR_FMT "; 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:" TARGET_ADDR_FMT " to r:" TARGET_ADDR_FMT,
-                         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, target_addr_t address,
                                uint32_t count, uint8_t *buffer)
 {
@@ -2837,7 +2533,7 @@ static int cortex_a_read_buffer(struct target *target, target_addr_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;
@@ -2850,7 +2546,7 @@ static int cortex_a_read_buffer(struct target *target, target_addr_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;
@@ -2871,7 +2567,7 @@ static int cortex_a_write_buffer(struct target *target, target_addr_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;
@@ -2884,7 +2580,7 @@ static int cortex_a_write_buffer(struct target *target, target_addr_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;
@@ -2962,21 +2658,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 */
@@ -3136,8 +2817,6 @@ static int cortex_a_init_arch_info(struct target *target,
        cortex_a->common_magic = CORTEX_A_COMMON_MAGIC;
        armv7a->arm.dap = dap;
 
-       cortex_a->fast_reg_read = 0;
-
        /* register arch-specific functions */
        armv7a->examine_debug_reason = NULL;
 
@@ -3152,15 +2831,15 @@ static int cortex_a_init_arch_info(struct target *target,
 
        /* REVISIT v7a setup should be in a v7a-specific routine */
        armv7a_init_arch_info(target, armv7a);
-       target_register_timer_callback(cortex_a_handle_target_request, 1, 1, target);
+       target_register_timer_callback(cortex_a_handle_target_request, 1,
+               TARGET_TIMER_TYPE_PERIODIC, target);
 
        return ERROR_OK;
 }
 
 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 cortex_a_common *cortex_a;
        struct adiv5_private_config *pc;
 
        if (target->private_config == NULL)
@@ -3168,8 +2847,13 @@ static int cortex_a_target_create(struct target *target, Jim_Interp *interp)
 
        pc = (struct adiv5_private_config *)target->private_config;
 
+       cortex_a = calloc(1, sizeof(struct cortex_a_common));
+       if (cortex_a == NULL) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+       cortex_a->common_magic = CORTEX_A_COMMON_MAGIC;
        cortex_a->armv7a_common.is_armv7r = false;
-
        cortex_a->armv7a_common.arm.arm_vfp_version = ARM_VFP_V3;
 
        return cortex_a_init_arch_info(target, cortex_a, pc->dap);
@@ -3177,14 +2861,19 @@ static int cortex_a_target_create(struct target *target, Jim_Interp *interp)
 
 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 cortex_a_common *cortex_a;
        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 = calloc(1, sizeof(struct cortex_a_common));
+       if (cortex_a == NULL) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+       cortex_a->common_magic = CORTEX_A_COMMON_MAGIC;
        cortex_a->armv7a_common.is_armv7r = true;
 
        return cortex_a_init_arch_info(target, cortex_a, pc->dap);
@@ -3193,7 +2882,20 @@ static int cortex_r4_target_create(struct target *target, Jim_Interp *interp)
 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);
@@ -3222,27 +2924,27 @@ static int cortex_a_mmu(struct target *target, int *enabled)
 static int cortex_a_virt2phys(struct target *target,
        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, (uint32_t)virt,
-                                                   (uint32_t *)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)
@@ -3265,63 +2967,6 @@ COMMAND_HANDLER(cortex_a_handle_dbginit_command)
 
        return cortex_a_init_debug_access(target);
 }
-COMMAND_HANDLER(cortex_a_handle_smp_off_command)
-{
-       struct target *target = get_current_target(CMD_CTX);
-       /* check target is an smp target */
-       struct target_list *head;
-       struct target *curr;
-       head = target->head;
-       target->smp = 0;
-       if (head != (struct target_list *)NULL) {
-               while (head != (struct target_list *)NULL) {
-                       curr = head->target;
-                       curr->smp = 0;
-                       head = head->next;
-               }
-               /*  fixes the target display to the debugger */
-               target->gdb_service->target = target;
-       }
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(cortex_a_handle_smp_on_command)
-{
-       struct target *target = get_current_target(CMD_CTX);
-       struct target_list *head;
-       struct target *curr;
-       head = target->head;
-       if (head != (struct target_list *)NULL) {
-               target->smp = 1;
-               while (head != (struct target_list *)NULL) {
-                       curr = head->target;
-                       curr->smp = 1;
-                       head = head->next;
-               }
-       }
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(cortex_a_handle_smp_gdb_command)
-{
-       struct target *target = get_current_target(CMD_CTX);
-       int retval = ERROR_OK;
-       struct target_list *head;
-       head = target->head;
-       if (head != (struct target_list *)NULL) {
-               if (CMD_ARGC == 1) {
-                       int coreid = 0;
-                       COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], coreid);
-                       if (ERROR_OK != retval)
-                               return retval;
-                       target->gdb_service->core[1] = coreid;
-
-               }
-               command_print(CMD_CTX, "gdb coreid  %" PRId32 " -> %" PRId32, target->gdb_service->core[0]
-                       , target->gdb_service->core[1]);
-       }
-       return ERROR_OK;
-}
 
 COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)
 {
@@ -3392,25 +3037,6 @@ static const struct command_registration cortex_a_exec_command_handlers[] = {
                .help = "Initialize core debug",
                .usage = "",
        },
-       {   .name = "smp_off",
-           .handler = cortex_a_handle_smp_off_command,
-           .mode = COMMAND_EXEC,
-           .help = "Stop smp handling",
-           .usage = "",},
-       {
-               .name = "smp_on",
-               .handler = cortex_a_handle_smp_on_command,
-               .mode = COMMAND_EXEC,
-               .help = "Restart smp handling",
-               .usage = "",
-       },
-       {
-               .name = "smp_gdb",
-               .handler = cortex_a_handle_smp_gdb_command,
-               .mode = COMMAND_EXEC,
-               .help = "display/fix current core played to gdb",
-               .usage = "",
-       },
        {
                .name = "maskisr",
                .handler = handle_cortex_a_mask_interrupts_command,
@@ -3421,11 +3047,17 @@ 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,
+       },
+       {
+               .chain = smp_command_handlers,
+       },
 
        COMMAND_REGISTRATION_DONE
 };
@@ -3461,6 +3093,7 @@ struct target_type cortexa_target = {
        .deassert_reset = cortex_a_deassert_reset,
 
        /* REVISIT allow exporting VFP3 registers ... */
+       .get_gdb_arch = arm_get_gdb_arch,
        .get_gdb_reg_list = arm_get_gdb_reg_list,
 
        .read_memory = cortex_a_read_memory,
@@ -3540,6 +3173,7 @@ struct target_type cortexr4_target = {
        .deassert_reset = cortex_a_deassert_reset,
 
        /* REVISIT allow exporting VFP3 registers ... */
+       .get_gdb_arch = arm_get_gdb_arch,
        .get_gdb_reg_list = arm_get_gdb_reg_list,
 
        .read_memory = cortex_a_read_phys_memory,

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)