This is an automated email from Gerrit. "Dietmar May <dietmar....@outlook.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6474
-- gerrit commit 90c934d6465538d471a549d9ecd352df60961819 Author: Dietmar May <dietmar....@outlook.com> Date: Thu Aug 19 11:10:18 2021 -0400 aarch64: implement 64 bit msr/mrs support within existing mcr/mrc cmd The existing mcr/mrc code checks whether it's in 32 bit mode, and silently bails without any warning if it's in 64 bit mode. This patch instead performs a msr / mrs operation when mcr or mrc is issued when in 64 bit mode. proc warm_reset {} { set _t [target current] echo "$_t warm reset" # write b0011 to RMR_EL3 for warm reset into 64-bit mode $_t aarch64 mcr 1 6 12 0 2 3 } Signed-off-by: Dietmar May <dietmar....@outlook.com> Change-Id: Ib8f198391bcee537bf0e555c357be0bedf628e14 diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 70e727cf9..f71c735a8 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -2953,6 +2953,113 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command) return ERROR_OK; } +/* Move to ARM register from coprocessor + * o0: Coprocessor number (0 - general, 1 - system) + * op1: Coprocessor opcode + * rd: destination register + * crn: first coprocessor operand + * crm: second coprocessor operand + * op2: Second coprocessor opcode + */ +#define ARMV8_MRS64(o0, op1, rd, crn, crm, op2) \ + (0xD5300000 \ + | (((o0) & 0x01) << 19) \ + | (((op1) & 0x07) << 16) \ + | (((crn) & 0x0F) << 12) \ + | (((crm) & 0x0F) << 8) \ + | (((op2) & 0x07) << 5) \ + | ((rd) & 0x1F) \ + ) + +/* Read coprocessor */ +static int dpm_mrs(struct target *target, int o0, + uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint64_t *value) +{ + struct aarch64_common *aarch64 = target_to_aarch64(target); + struct armv8_common *armv8 = &aarch64->armv8_common; + struct arm_dpm *dpm = &armv8->dpm; + int retval; + +#if 0 //todo aarch64_post_debug_entry brackets instr_read_data_r0 + if (target_mode != ARM_MODE_ANY) + armv8_dpm_modeswitch(dpm, target_mode); +#else + retval = dpm->prepare(dpm); + if (retval != ERROR_OK) + return retval; +#endif + + uint32_t instr = ARMV8_MRS64(o0, op1, 0, crn, crm, op2); + + LOG_DEBUG("MRS p%d, %d, r0, c%d, c%d, %d - %08x", o0, + (int) op1, (int) crn, (int) crm, (int) op2, instr); + + /* read coprocessor register into R0; return via DCC */ + retval = dpm->instr_read_data_r0_64(dpm, instr, value); + +#if 0 //todo aarch64_post_debug_entry brackets instr_read_data_r0 + if (target_mode != ARM_MODE_ANY) + armv8_dpm_modeswitch(dpm, ARM_MODE_ANY); +#else + /* (void) */ dpm->finish(dpm); +#endif + + return retval; +} + +/* Move to coprocessor from ARM register + * o0: Coprocessor number (0 - general, 1 - system) + * op1: Coprocessor opcode + * rd: destination register + * crn: first coprocessor operand + * crm: second coprocessor operand + * op2: Second coprocessor opcode + */ +#define ARMV8_MSR64(o0, op1, rd, crn, crm, op2) \ + (0xD5100000 \ + | (((o0) & 0x01) << 19) \ + | (((op1) & 0x07) << 16) \ + | (((crn) & 0x0F) << 12) \ + | (((crm) & 0x0F) << 8) \ + | (((op2) & 0x07) << 5) \ + | ((rd) & 0x1F) \ + ) + +static int dpm_msr(struct target *target, int o0, + uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint64_t value) +{ + struct aarch64_common *aarch64 = target_to_aarch64(target); + struct armv8_common *armv8 = &aarch64->armv8_common; + struct arm_dpm *dpm = &armv8->dpm; + int retval; + +#if 0 //todo aarch64_restore_system_control_reg brackets instr_write_data_r0 + if (target_mode != ARM_MODE_ANY) + armv8_dpm_modeswitch(dpm, target_mode); +#else + retval = dpm->prepare(dpm); + if (retval != ERROR_OK) + return retval; +#endif + + uint32_t instr = ARMV8_MSR64(o0, op1, 0, crn, crm, op2); + + LOG_TRACE("MSR p%d, %d, r0, c%d, c%d, %d - %08x = 0x%016" PRIx64, o0, + (int) op1, (int) crn, (int) crm, (int) op2, instr, value); + + /* read DCC into r0; then write coprocessor register from R0 */ + retval = dpm->instr_write_data_r0_64(dpm, instr, value); + +#if 0 //todo aarch64_restore_system_control_reg brackets instr_write_data_r0 + if (target_mode != ARM_MODE_ANY) + armv8_dpm_modeswitch(dpm, ARM_MODE_ANY); +#else + /* (void) */ dpm->finish(dpm); +#endif + + return retval; +} + static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { struct command *c = jim_to_command(interp); @@ -2989,12 +3096,9 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) return JIM_ERR; } - if (target->state != TARGET_HALTED) + if (target->state != TARGET_HALTED) { + LOG_ERROR("%s: target not halted", target_name(target)); return ERROR_TARGET_NOT_HALTED; - - if (arm->core_state == ARM_STATE_AARCH64) { - LOG_ERROR("%s: not 32-bit arm target", target_name(target)); - return JIM_ERR; } if (argc != arg_cnt) { @@ -3007,7 +3111,6 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) uint32_t op2; uint32_t crn; uint32_t crm; - uint32_t value; long l; /* NOTE: parameter sequence matches ARM instruction set usage: @@ -3065,27 +3168,53 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) } op2 = l; - value = 0; - if (is_mcr == true) { - retval = Jim_GetLong(interp, argv[6], &l); - if (retval != JIM_OK) - return retval; - value = l; + if (arm->core_state == ARM_STATE_AARCH64) { + jim_wide lw; + retval = Jim_GetWide(interp, argv[6], &lw); + if (retval != JIM_OK) + return retval; + uint64_t value = lw; - /* NOTE: parameters reordered! */ - /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ - retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); - if (retval != ERROR_OK) - return JIM_ERR; + /* NOTE: parameters reordered! */ + /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ + retval = dpm_msr(target, cpnum, op1, op2, crn, crm, value); + if (retval != ERROR_OK) + return JIM_ERR; + } else { + retval = Jim_GetLong(interp, argv[6], &l); + if (retval != JIM_OK) + return retval; + uint32_t value = l; + + /* NOTE: parameters reordered! */ + /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ + retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); + if (retval != ERROR_OK) + return JIM_ERR; + } } else { - /* NOTE: parameters reordered! */ - /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ - retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); - if (retval != ERROR_OK) - return JIM_ERR; + if (arm->core_state == ARM_STATE_AARCH64) { + uint64_t value; + /* NOTE: parameters reordered! */ + /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ + retval = dpm_mrs(target, cpnum, op1, op2, crn, crm, &value); + if (retval != ERROR_OK) + return JIM_ERR; - Jim_SetResult(interp, Jim_NewIntObj(interp, value)); + jim_wide lw = value; + Jim_SetResult(interp, Jim_NewWideObj(interp, lw)); + } else { + uint32_t value; + /* NOTE: parameters reordered! */ + /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ + retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); + if (retval != ERROR_OK) + return JIM_ERR; + + l = value; + Jim_SetResult(interp, Jim_NewIntObj(interp, value)); + } } return JIM_OK; --