X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fcortex_a.c;h=f9ffccd08a4144bd0fb45b2feb6653aa6730632d;hp=7da57b4980cb09e3377570368b7584a59f1b5a37;hb=b0698501b0e789091e9f9f1427b32af304888769;hpb=dc574aa1da291405c6778383c1ad3b252602aee7 diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 7da57b4980..f9ffccd08a 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -106,6 +106,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 +114,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 +136,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 +202,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 +228,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 +240,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 +250,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 +266,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 +274,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 +299,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 +327,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 +337,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 +371,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 +382,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 *)(®file[1]), 4, 15, address); return retval; @@ -386,7 +395,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 +431,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 +443,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 +457,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 +479,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 +535,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 +560,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 +574,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 +587,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 +602,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) @@ -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; @@ -948,13 +951,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 +964,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 +1054,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 +1092,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 +1102,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 +1110,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; @@ -1207,13 +1209,12 @@ static int cortex_a_debug_entry(struct target *target) 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 +1226,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 +1238,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) @@ -1350,17 +1351,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 +1381,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 +1443,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 +1903,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,7 +1912,9 @@ 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; @@ -1952,8 +1966,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 +1981,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 +2002,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 +2023,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 +2056,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; @@ -2129,7 +2140,6 @@ static int cortex_a_write_apb_ab_memory_slow(struct target *target, * - 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 +2161,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; @@ -2203,7 +2213,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,13 +2221,13 @@ 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); } @@ -2229,7 +2238,6 @@ static int cortex_a_write_apb_ab_memory(struct target *target, /* Write memory through APB-AP. */ 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; @@ -2244,13 +2252,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 +2277,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; @@ -2301,7 +2309,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 +2321,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 +2355,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; @@ -2375,7 +2383,6 @@ static int cortex_a_read_apb_ab_memory_slow(struct target *target, * - 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 +2427,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; @@ -2450,7 +2457,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 +2479,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 +2490,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 +2524,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; @@ -2534,7 +2540,6 @@ static int cortex_a_read_apb_ab_memory(struct target *target, /* Read memory through APB-AP. */ 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; @@ -2549,13 +2554,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 +2579,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; @@ -2606,7 +2611,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 +2645,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; @@ -2667,17 +2672,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 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); + return retval; } @@ -2707,7 +2720,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 +2748,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 +2757,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 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); return retval; } @@ -2787,7 +2807,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 +2836,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 +2913,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 +2923,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; + } } } @@ -2935,12 +2959,11 @@ static int cortex_a_examine_first(struct target *target) 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 */ retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap); @@ -2948,17 +2971,31 @@ static int cortex_a_examine_first(struct target *target) 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) { + 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; + else + LOG_WARNING("Could not initialize AHB-AP for memory access - using APB-AP"); + } else { /* 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 */ @@ -2966,11 +3003,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 +3019,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 +3066,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 +3078,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 +3086,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 +3123,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 +3171,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 +3247,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 +3355,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 +3371,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 +3434,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 };