cortex_a: add 'dacrfixup' to cortex-a command group
work around issues with software breakpoints when the text segment is mapped read-only by the OS. Set DACR to "all-manager" to bypass TLB permission checks on memory access. Change-Id: I79fd9b32b04a4d538d489896470ee30b26b72b30 Signed-off-by: Matthias Welwarsky <matthias@welwarsky.de> Reviewed-on: http://openocd.zylin.com/3107 Tested-by: jenkins Reviewed-by: Paul Fertser <fercerpav@gmail.com>__archive__
parent
082417fc71
commit
5bee7f5b2c
|
@ -7678,6 +7678,13 @@ Disabled by default
|
||||||
display information about target caches
|
display information about target caches
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn Command {cortex_a dacrfixup [@option{on}|@option{off}]}
|
||||||
|
Work around issues with software breakpoints when the program text is
|
||||||
|
mapped read-only by the operating system. This option sets the CP15 DACR
|
||||||
|
to "all-manager" to bypass MMU permission checks on memory access.
|
||||||
|
Defaults to 'off'.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@deffn Command {cortex_a dbginit}
|
@deffn Command {cortex_a dbginit}
|
||||||
Initialize core debug
|
Initialize core debug
|
||||||
Enables debug by unlocking the Software Lock and clearing sticky powerdown indications
|
Enables debug by unlocking the Software Lock and clearing sticky powerdown indications
|
||||||
|
|
|
@ -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)
|
static int cortex_a_prep_memaccess(struct target *target, int phys_access)
|
||||||
{
|
{
|
||||||
struct armv7a_common *armv7a = target_to_armv7a(target);
|
struct armv7a_common *armv7a = target_to_armv7a(target);
|
||||||
|
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
|
||||||
int mmu_enabled = 0;
|
int mmu_enabled = 0;
|
||||||
|
|
||||||
if (phys_access == 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);
|
cortex_a_mmu(target, &mmu_enabled);
|
||||||
if (mmu_enabled)
|
if (mmu_enabled)
|
||||||
cortex_a_mmu_modify(target, 1);
|
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 {
|
} else {
|
||||||
cortex_a_mmu(target, &mmu_enabled);
|
cortex_a_mmu(target, &mmu_enabled);
|
||||||
if (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)
|
static int cortex_a_post_memaccess(struct target *target, int phys_access)
|
||||||
{
|
{
|
||||||
struct armv7a_common *armv7a = target_to_armv7a(target);
|
struct armv7a_common *armv7a = target_to_armv7a(target);
|
||||||
|
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
|
||||||
|
|
||||||
if (phys_access == 0) {
|
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);
|
dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
|
||||||
} else {
|
} else {
|
||||||
int mmu_enabled = 0;
|
int mmu_enabled = 0;
|
||||||
|
@ -1040,6 +1054,7 @@ static int cortex_a_internal_restore(struct target *target, int current,
|
||||||
buf_set_u32(arm->pc->value, 0, 32, resume_pc);
|
buf_set_u32(arm->pc->value, 0, 32, resume_pc);
|
||||||
arm->pc->dirty = 1;
|
arm->pc->dirty = 1;
|
||||||
arm->pc->valid = 1;
|
arm->pc->valid = 1;
|
||||||
|
|
||||||
/* restore dpm_mode at system halt */
|
/* restore dpm_mode at system halt */
|
||||||
dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
|
dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
|
||||||
/* called it now before restoring context because it uses cpu
|
/* called it now before restoring context because it uses cpu
|
||||||
|
@ -1336,6 +1351,16 @@ static int cortex_a_post_debug_entry(struct target *target)
|
||||||
(cortex_a->cp15_control_reg & 0x1000U) ? 1 : 0;
|
(cortex_a->cp15_control_reg & 0x1000U) ? 1 : 0;
|
||||||
cortex_a->curr_mode = armv7a->arm.core_mode;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3325,6 +3350,32 @@ COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)
|
||||||
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[] = {
|
static const struct command_registration cortex_a_exec_command_handlers[] = {
|
||||||
{
|
{
|
||||||
.name = "cache_info",
|
.name = "cache_info",
|
||||||
|
@ -3366,7 +3417,14 @@ static const struct command_registration cortex_a_exec_command_handlers[] = {
|
||||||
.help = "mask cortex_a interrupts",
|
.help = "mask cortex_a interrupts",
|
||||||
.usage = "['on'|'off']",
|
.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
|
COMMAND_REGISTRATION_DONE
|
||||||
};
|
};
|
||||||
|
|
|
@ -60,6 +60,11 @@ enum cortex_a_isrmasking_mode {
|
||||||
CORTEX_A_ISRMASK_ON,
|
CORTEX_A_ISRMASK_ON,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum cortex_a_dacrfixup_mode {
|
||||||
|
CORTEX_A_DACRFIXUP_OFF,
|
||||||
|
CORTEX_A_DACRFIXUP_ON
|
||||||
|
};
|
||||||
|
|
||||||
struct cortex_a_brp {
|
struct cortex_a_brp {
|
||||||
int used;
|
int used;
|
||||||
int type;
|
int type;
|
||||||
|
@ -78,9 +83,12 @@ struct cortex_a_common {
|
||||||
uint32_t cp15_control_reg;
|
uint32_t cp15_control_reg;
|
||||||
/* latest cp15 register value written and cpsr processor mode */
|
/* latest cp15 register value written and cpsr processor mode */
|
||||||
uint32_t cp15_control_reg_curr;
|
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;
|
enum arm_mode curr_mode;
|
||||||
|
|
||||||
|
|
||||||
/* Breakpoint register pairs */
|
/* Breakpoint register pairs */
|
||||||
int brp_num_context;
|
int brp_num_context;
|
||||||
int brp_num;
|
int brp_num;
|
||||||
|
@ -96,6 +104,7 @@ struct cortex_a_common {
|
||||||
uint32_t didr;
|
uint32_t didr;
|
||||||
|
|
||||||
enum cortex_a_isrmasking_mode isrmasking_mode;
|
enum cortex_a_isrmasking_mode isrmasking_mode;
|
||||||
|
enum cortex_a_dacrfixup_mode dacrfixup_mode;
|
||||||
|
|
||||||
struct armv7a_common armv7a_common;
|
struct armv7a_common armv7a_common;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue