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,
+ armv7a->debug_base + CPUDBG_DSCR, &dscr);
+ if (ERROR_OK != retval)
+ return retval;
+
+ /* clear bitfield */
+ dscr &= ~bit_mask;
+ /* put new value */
+ dscr |= value & bit_mask;
+
+ /* write new DSCR */
+ retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_DSCR, dscr);
+ return retval;
+}
+
static int cortex_a_step(struct target *target, int current, uint32_t address,
int handle_breakpoints)
{
+ 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 breakpoint *breakpoint = NULL;
stepbreakpoint.type = BKPT_HARD;
stepbreakpoint.set = 0;
+ /* Disable interrupts during single step if requested */
+ if (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) {
+ retval = cortex_a_set_dscr_bits(target, DSCR_INT_DIS, DSCR_INT_DIS);
+ if (ERROR_OK != retval)
+ return retval;
+ }
+
/* Break on IVA mismatch */
cortex_a_set_breakpoint(target, &stepbreakpoint, 0x04);
cortex_a_unset_breakpoint(target, &stepbreakpoint);
+ /* Re-enable interrupts if they were disabled */
+ if (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) {
+ retval = cortex_a_set_dscr_bits(target, DSCR_INT_DIS, 0);
+ if (ERROR_OK != retval)
+ return retval;
+ }
+
+
target->debug_reason = DBG_REASON_BREAKPOINT;
if (breakpoint)
uint32_t count, uint8_t *buffer)
{
struct armv7a_common *armv7a = target_to_armv7a(target);
- struct adiv5_dap *swjdp = armv7a->arm.dap;
int retval = ERROR_COMMAND_SYNTAX_ERROR;
- uint8_t apsel = swjdp->apsel;
+
LOG_DEBUG("Reading memory at real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32,
address, size, count);
if (count && buffer) {
-
- if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
-
- /* read memory through AHB-AP */
- retval = mem_ap_sel_read_buf(swjdp, armv7a->memory_ap, buffer, size, count, address);
- } else {
-
- /* read memory through APB-AP */
- if (!armv7a->is_armv7r) {
- /* disable mmu */
- retval = cortex_a_mmu_modify(target, 0);
- if (retval != ERROR_OK)
- return retval;
- }
- retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
+ /* read memory through APB-AP */
+ if (!armv7a->is_armv7r) {
+ /* disable mmu */
+ retval = cortex_a_mmu_modify(target, 0);
+ if (retval != ERROR_OK)
+ return retval;
}
+ retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
}
return retval;
}
uint32_t count, const uint8_t *buffer)
{
struct armv7a_common *armv7a = target_to_armv7a(target);
- struct adiv5_dap *swjdp = armv7a->arm.dap;
int retval = ERROR_COMMAND_SYNTAX_ERROR;
- uint8_t apsel = swjdp->apsel;
LOG_DEBUG("Writing memory to real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
size, count);
if (count && buffer) {
-
- if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
-
- /* write memory through AHB-AP */
- retval = mem_ap_sel_write_buf(swjdp, armv7a->memory_ap, buffer, size, count, address);
- } else {
-
- /* write memory through APB-AP */
- if (!armv7a->is_armv7r) {
- retval = cortex_a_mmu_modify(target, 0);
- if (retval != ERROR_OK)
- return retval;
- }
- return cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
+ /* write memory through APB-AP */
+ if (!armv7a->is_armv7r) {
+ retval = cortex_a_mmu_modify(target, 0);
+ if (retval != ERROR_OK)
+ return retval;
}
+ return cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
}
-
/* REVISIT this op is generic ARMv7-A/R stuff */
if (retval == ERROR_OK && target->state == TARGET_HALTED) {
struct arm_dpm *dpm = armv7a->arm.dpm;
LOG_DEBUG("target->coreid %" PRId32 " DBGPRSR 0x%" PRIx32, target->coreid, dbg_osreg);
armv7a->arm.core_type = ARM_MODE_MON;
- retval = cortex_a_dpm_setup(cortex_a, didr);
- if (retval != ERROR_OK)
- return retval;
+
+ /* Avoid recreating the registers cache */
+ if (!target_was_examined(target)) {
+ retval = cortex_a_dpm_setup(cortex_a, didr);
+ if (retval != ERROR_OK)
+ return retval;
+ }
/* Setup Breakpoint Register Pairs */
cortex_a->brp_num = ((didr >> 24) & 0x0F) + 1;
return cortex_a_init_arch_info(target, cortex_a, target->tap);
}
+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;
+
+ free(cortex_a->brp_list);
+ free(dpm->dbp);
+ free(dpm->dwp);
+ free(cortex_a);
+}
static int cortex_a_mmu(struct target *target, int *enabled)
{
return ERROR_OK;
}
+COMMAND_HANDLER(handle_cortex_a_mask_interrupts_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_maskisr_modes[] = {
+ { .name = "off", .value = CORTEX_A_ISRMASK_OFF },
+ { .name = "on", .value = CORTEX_A_ISRMASK_ON },
+ { .name = NULL, .value = -1 },
+ };
+ 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)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ cortex_a->isrmasking_mode = n->value;
+
+ }
+
+ n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode);
+ command_print(CMD_CTX, "cortex_a interrupt mask %s", n->name);
+
+ return ERROR_OK;
+}
+
static const struct command_registration cortex_a_exec_command_handlers[] = {
{
.name = "cache_info",
.help = "display/fix current core played to gdb",
.usage = "",
},
+ {
+ .name = "maskisr",
+ .handler = handle_cortex_a_mask_interrupts_command,
+ .mode = COMMAND_EXEC,
+ .help = "mask cortex_a interrupts",
+ .usage = "['on'|'off']",
+ },
COMMAND_REGISTRATION_DONE
.target_create = cortex_a_target_create,
.init_target = cortex_a_init_target,
.examine = cortex_a_examine,
+ .deinit_target = cortex_a_deinit_target,
.read_phys_memory = cortex_a_read_phys_memory,
.write_phys_memory = cortex_a_write_phys_memory,
.help = "Initialize core debug",
.usage = "",
},
+ {
+ .name = "maskisr",
+ .handler = handle_cortex_a_mask_interrupts_command,
+ .mode = COMMAND_EXEC,
+ .help = "mask cortex_r4 interrupts",
+ .usage = "['on'|'off']",
+ },
COMMAND_REGISTRATION_DONE
};
.target_create = cortex_r4_target_create,
.init_target = cortex_a_init_target,
.examine = cortex_a_examine,
+ .deinit_target = cortex_a_deinit_target,
};