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) {
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)
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;
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
(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;
}
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",
.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
};
CORTEX_A_ISRMASK_ON,
};
+enum cortex_a_dacrfixup_mode {
+ CORTEX_A_DACRFIXUP_OFF,
+ CORTEX_A_DACRFIXUP_ON
+};
+
struct cortex_a_brp {
int used;
int type;
uint32_t cp15_control_reg;
/* latest cp15 register value written and cpsr processor mode */
uint32_t cp15_control_reg_curr;
+ /* auxiliary control reg */
+ uint32_t cp15_aux_control_reg;
+ /* DACR */
+ uint32_t cp15_dacr_reg;
enum arm_mode curr_mode;
-
/* Breakpoint register pairs */
int brp_num_context;
int brp_num;
uint32_t didr;
enum cortex_a_isrmasking_mode isrmasking_mode;
+ enum cortex_a_dacrfixup_mode dacrfixup_mode;
struct armv7a_common armv7a_common;