Skip to content

Commit

Permalink
target: aarch64: access reg ELR_EL2 only in EL2 and EL3
Browse files Browse the repository at this point in the history
The register ELR_EL2 is accessible and it's content is relevant
only when the target is in EL2 or EL3.
Virtualization SW in EL1 can also access it, but this either
triggers a trap to EL2 or returns ELR_EL1. Debugger should not mix
the real ELR_EL2 with the virtual register.

Without this patch, an error:
	Error: Opcode 0xd53c4020, DSCR.ERR=1, DSCR.EL=1
is triggered by GDB register window or through GDB command
	x/p $ELR_EL2
or through OpenOCD command
	reg ELR_EL2

Detect the EL and return error if the register cannot be accessed.

Change-Id: Idf02b42a7339df83260c1e44ceabbb05fbf392b9
Signed-off-by: Antonio Borneo <[email protected]>
Reviewed-on: https://review.openocd.org/c/openocd/+/8271
Tested-by: jenkins
  • Loading branch information
borneoa committed Jun 23, 2024
1 parent 405e787 commit 190176a
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/target/armv8.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,11 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv
ARMV8_MRS(SYSTEM_ELR_EL1, 0), &value_64);
break;
case ARMV8_ELR_EL2:
if (curel < SYSTEM_CUREL_EL2) {
LOG_DEBUG("ELR_EL2 not accessible in EL%u", curel);
retval = ERROR_FAIL;
break;
}
retval = dpm->instr_read_data_r0_64(dpm,
ARMV8_MRS(SYSTEM_ELR_EL2, 0), &value_64);
break;
Expand Down Expand Up @@ -454,6 +459,11 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu
ARMV8_MSR_GP(SYSTEM_ELR_EL1, 0), value_64);
break;
case ARMV8_ELR_EL2:
if (curel < SYSTEM_CUREL_EL2) {
LOG_DEBUG("ELR_EL2 not accessible in EL%u", curel);
retval = ERROR_FAIL;
break;
}
retval = dpm->instr_write_data_r0_64(dpm,
ARMV8_MSR_GP(SYSTEM_ELR_EL2, 0), value_64);
break;
Expand Down

0 comments on commit 190176a

Please sign in to comment.