diff options
author | Antonio Borneo <borneo.antonio@gmail.com> | 2024-05-13 18:19:55 +0200 |
---|---|---|
committer | Antonio Borneo <borneo.antonio@gmail.com> | 2024-06-23 09:28:32 +0000 |
commit | 8c75e4760333a4e0408bdf9dd58a702e4fb67c51 (patch) | |
tree | 675c155b3266e49a3dfa81d79596c3122aa8dbc3 | |
parent | bcd6a1022322f67f25f74af2dfe40d440d382e74 (diff) | |
download | riscv-openocd-8c75e4760333a4e0408bdf9dd58a702e4fb67c51.zip riscv-openocd-8c75e4760333a4e0408bdf9dd58a702e4fb67c51.tar.gz riscv-openocd-8c75e4760333a4e0408bdf9dd58a702e4fb67c51.tar.bz2 |
target: aarch64: access reg ELR_EL3 only in EL3
The register ELR_EL3 is accessible and it's content is relevant
only when the target is in EL3.
Without this patch, an error:
Error: Opcode 0xd53e4020, DSCR.ERR=1, DSCR.EL=1
is triggered by GDB register window or through GDB command
x/p $ELR_EL3
or through OpenOCD command
reg ELR_EL3
Detect the EL and return error if the register cannot be accessed.
Change-Id: I545abb196e5c34e462c7e5d5d3ec952e588642da
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8268
Tested-by: jenkins
-rw-r--r-- | src/target/armv8.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/target/armv8.c b/src/target/armv8.c index 8d97902..e36e2f6 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -278,6 +278,7 @@ static int armv8_get_pauth_mask(struct armv8_common *armv8, uint64_t *mask) static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regval) { struct arm_dpm *dpm = &armv8->dpm; + unsigned int curel = armv8_curel_from_core_mode(dpm->arm->core_mode); int retval; uint32_t value; uint64_t value_64; @@ -322,6 +323,11 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv ARMV8_MRS(SYSTEM_ELR_EL2, 0), &value_64); break; case ARMV8_ELR_EL3: + if (curel < SYSTEM_CUREL_EL3) { + LOG_DEBUG("ELR_EL3 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_ELR_EL3, 0), &value_64); break; @@ -396,6 +402,7 @@ static int armv8_read_reg_simdfp_aarch64(struct armv8_common *armv8, int regnum, static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t value_64) { struct arm_dpm *dpm = &armv8->dpm; + unsigned int curel = armv8_curel_from_core_mode(dpm->arm->core_mode); int retval; uint32_t value; @@ -443,6 +450,11 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu ARMV8_MSR_GP(SYSTEM_ELR_EL2, 0), value_64); break; case ARMV8_ELR_EL3: + if (curel < SYSTEM_CUREL_EL3) { + LOG_DEBUG("ELR_EL3 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } retval = dpm->instr_write_data_r0_64(dpm, ARMV8_MSR_GP(SYSTEM_ELR_EL3, 0), value_64); break; |