target/cortex_a: remove duplicate code to read target registers

The functions cortex_a_dap_{read,write}_coreregister_u32() are
duplicate of the functions dpm_{read,write}_reg().

Remove both duplicated functions in cortex_a.c while export only
dpm_read_reg(), since dpm_write_reg() is currently not used.
Rename dpm_read_reg() as arm_dpm_read_reg() to keep uniform the
naming style.

Change-Id: I501bc99dc402039e630c47917a086a0bb382782c
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/4747
Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
Tested-by: jenkins
bscan_tunnel
Antonio Borneo 2018-10-07 16:27:27 +02:00 committed by Matthias Welwarsky
parent cf9c0fba9b
commit 29c81a8051
3 changed files with 9 additions and 160 deletions

View File

@ -168,7 +168,7 @@ static int dpm_read_reg_u64(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
} }
/* just read the register -- rely on the core mode being right */ /* just read the register -- rely on the core mode being right */
static int dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum) int arm_dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
{ {
uint32_t value; uint32_t value;
int retval; int retval;
@ -352,7 +352,7 @@ int arm_dpm_read_current_registers(struct arm_dpm *dpm)
for (unsigned i = 0; i < 2; i++) { for (unsigned i = 0; i < 2; i++) {
r = arm->core_cache->reg_list + i; r = arm->core_cache->reg_list + i;
if (!r->valid) { if (!r->valid) {
retval = dpm_read_reg(dpm, r, i); retval = arm_dpm_read_reg(dpm, r, i);
if (retval != ERROR_OK) if (retval != ERROR_OK)
goto fail; goto fail;
} }
@ -372,7 +372,7 @@ int arm_dpm_read_current_registers(struct arm_dpm *dpm)
if (r->valid) if (r->valid)
continue; continue;
retval = dpm_read_reg(dpm, r, i); retval = arm_dpm_read_reg(dpm, r, i);
if (retval != ERROR_OK) if (retval != ERROR_OK)
goto fail; goto fail;
} }
@ -676,7 +676,7 @@ static int arm_dpm_read_core_reg(struct target *target, struct reg *r,
goto fail; goto fail;
} }
retval = dpm_read_reg(dpm, r, regnum); retval = arm_dpm_read_reg(dpm, r, regnum);
if (retval != ERROR_OK) if (retval != ERROR_OK)
goto fail; goto fail;
/* always clean up, regardless of error */ /* always clean up, regardless of error */
@ -784,7 +784,7 @@ static int arm_dpm_full_context(struct target *target)
continue; continue;
/* CPSR was read, so "R16" must mean SPSR */ /* CPSR was read, so "R16" must mean SPSR */
retval = dpm_read_reg(dpm, retval = arm_dpm_read_reg(dpm,
&cache->reg_list[i], &cache->reg_list[i],
(r->num == 16) ? 17 : r->num); (r->num == 16) ? 17 : r->num);
if (retval != ERROR_OK) if (retval != ERROR_OK)

View File

@ -152,6 +152,7 @@ struct arm_dpm {
int arm_dpm_setup(struct arm_dpm *dpm); int arm_dpm_setup(struct arm_dpm *dpm);
int arm_dpm_initialize(struct arm_dpm *dpm); int arm_dpm_initialize(struct arm_dpm *dpm);
int arm_dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum);
int arm_dpm_read_current_registers(struct arm_dpm *); int arm_dpm_read_current_registers(struct arm_dpm *);
int arm_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode); int arm_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode);

View File

@ -71,10 +71,6 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target,
struct breakpoint *breakpoint); struct breakpoint *breakpoint);
static int cortex_a_unset_breakpoint(struct target *target, static int cortex_a_unset_breakpoint(struct target *target,
struct breakpoint *breakpoint); 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(struct target *target, int *enabled);
static int cortex_a_mmu_modify(struct target *target, int enable); static int cortex_a_mmu_modify(struct target *target, int enable);
static int cortex_a_virt2phys(struct target *target, static int cortex_a_virt2phys(struct target *target,
@ -307,147 +303,6 @@ static int cortex_a_exec_opcode(struct target *target,
return retval; 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;
}
__attribute__((unused))
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 */ /* Write to memory mapped registers directly with no cache or mmu handling */
static int cortex_a_dap_write_memap_register_u32(struct target *target, static int cortex_a_dap_write_memap_register_u32(struct target *target,
uint32_t address, uint32_t address,
@ -1158,12 +1013,11 @@ static int cortex_a_resume(struct target *target, int current,
static int cortex_a_debug_entry(struct target *target) static int cortex_a_debug_entry(struct target *target)
{ {
uint32_t spsr, dscr; uint32_t dscr;
int retval = ERROR_OK; int retval = ERROR_OK;
struct cortex_a_common *cortex_a = target_to_cortex_a(target); struct cortex_a_common *cortex_a = target_to_cortex_a(target);
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm *arm = &armv7a->arm; struct arm *arm = &armv7a->arm;
struct reg *reg;
LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a->cpudbg_dscr); LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a->cpudbg_dscr);
@ -1206,16 +1060,10 @@ static int cortex_a_debug_entry(struct target *target)
return retval; return retval;
if (arm->spsr) { if (arm->spsr) {
/* read Saved PSR */ /* read SPSR */
retval = cortex_a_dap_read_coreregister_u32(target, &spsr, 17); retval = arm_dpm_read_reg(&armv7a->dpm, arm->spsr, 17);
/* store current spsr */
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
reg = arm->spsr;
buf_set_u32(reg->value, 0, 32, spsr);
reg->valid = 1;
reg->dirty = 0;
} }
#if 0 #if 0