aboutsummaryrefslogtreecommitdiff
path: root/src/target/armv8.c
diff options
context:
space:
mode:
authorEvgeniy Naydanov <evgeniy.naydanov@syntacore.com>2024-06-25 14:51:18 +0300
committerEvgeniy Naydanov <evgeniy.naydanov@syntacore.com>2024-06-25 14:51:18 +0300
commit2eedd74197f12fb8c30f259207430713291e8ec0 (patch)
tree8a27b3ebbdddb49c32477151bc66e339e84b46fe /src/target/armv8.c
parentfdd07f127998f8669784fa64b67a43dea97c1837 (diff)
parentad87fbd1cf28760795c4e18f3318a2d720e5a8a6 (diff)
downloadriscv-openocd-2eedd74197f12fb8c30f259207430713291e8ec0.zip
riscv-openocd-2eedd74197f12fb8c30f259207430713291e8ec0.tar.gz
riscv-openocd-2eedd74197f12fb8c30f259207430713291e8ec0.tar.bz2
Merge up to ad87fbd1cf28760795c4e18f3318a2d720e5a8a6 from upstream
Conflicts: * `doc/openocd.texi`: due to d382c95d57c0ad9ed2dcc83c95404babb7647708, resolved by selecting the upstream version. * `src/server/gdb_server.c`: between 944fe66f104e356c5fcd2b5c25200cebef9b389c and 92e8823ebdb6d01b41bb5d79af49501d525acd1d. Resolved by adopting the use of `LOG_TARGET_*`. * `src/target/target.c`: between 639e68a621b7ae8c4a296ca7e45b47075268fded and c5358c84ad0d3e7497498e0457cec7785f72910a, selected the version from `riscv-openocd`. Change-Id: Ic1327f25e147945e0ec82947a82452501e8ee5de
Diffstat (limited to 'src/target/armv8.c')
-rw-r--r--src/target/armv8.c180
1 files changed, 132 insertions, 48 deletions
diff --git a/src/target/armv8.c b/src/target/armv8.c
index bf582ff..b54ef13 100644
--- a/src/target/armv8.c
+++ b/src/target/armv8.c
@@ -278,10 +278,14 @@ 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;
+ if (!regval)
+ return ERROR_FAIL;
+
switch (regnum) {
case 0 ... 30:
retval = dpm->instr_read_data_dcc_64(dpm,
@@ -311,46 +315,85 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv
value_64 = value;
break;
case ARMV8_ELR_EL1:
+ if (curel < SYSTEM_CUREL_EL1) {
+ LOG_DEBUG("ELR_EL1 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
retval = dpm->instr_read_data_r0_64(dpm,
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;
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;
case ARMV8_ESR_EL1:
- retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS(SYSTEM_ESR_EL1, 0), &value);
- value_64 = value;
+ if (curel < SYSTEM_CUREL_EL1) {
+ LOG_DEBUG("ESR_EL1 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_read_data_r0_64(dpm,
+ ARMV8_MRS(SYSTEM_ESR_EL1, 0), &value_64);
break;
case ARMV8_ESR_EL2:
- retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS(SYSTEM_ESR_EL2, 0), &value);
- value_64 = value;
+ if (curel < SYSTEM_CUREL_EL2) {
+ LOG_DEBUG("ESR_EL2 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_read_data_r0_64(dpm,
+ ARMV8_MRS(SYSTEM_ESR_EL2, 0), &value_64);
break;
case ARMV8_ESR_EL3:
- retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS(SYSTEM_ESR_EL3, 0), &value);
- value_64 = value;
+ if (curel < SYSTEM_CUREL_EL3) {
+ LOG_DEBUG("ESR_EL3 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_read_data_r0_64(dpm,
+ ARMV8_MRS(SYSTEM_ESR_EL3, 0), &value_64);
break;
case ARMV8_SPSR_EL1:
- retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS(SYSTEM_SPSR_EL1, 0), &value);
- value_64 = value;
+ if (curel < SYSTEM_CUREL_EL1) {
+ LOG_DEBUG("SPSR_EL1 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_read_data_r0_64(dpm,
+ ARMV8_MRS(SYSTEM_SPSR_EL1, 0), &value_64);
break;
case ARMV8_SPSR_EL2:
- retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS(SYSTEM_SPSR_EL2, 0), &value);
- value_64 = value;
+ if (curel < SYSTEM_CUREL_EL2) {
+ LOG_DEBUG("SPSR_EL2 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_read_data_r0_64(dpm,
+ ARMV8_MRS(SYSTEM_SPSR_EL2, 0), &value_64);
break;
case ARMV8_SPSR_EL3:
- retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS(SYSTEM_SPSR_EL3, 0), &value);
- value_64 = value;
+ if (curel < SYSTEM_CUREL_EL3) {
+ LOG_DEBUG("SPSR_EL3 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_read_data_r0_64(dpm,
+ ARMV8_MRS(SYSTEM_SPSR_EL3, 0), &value_64);
break;
case ARMV8_PAUTH_CMASK:
case ARMV8_PAUTH_DMASK:
@@ -361,10 +404,8 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv
break;
}
- if (retval == ERROR_OK && regval)
+ if (retval == ERROR_OK)
*regval = value_64;
- else
- retval = ERROR_FAIL;
return retval;
}
@@ -395,6 +436,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;
@@ -434,46 +476,85 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu
break;
/* registers clobbered by taking exception in debug state */
case ARMV8_ELR_EL1:
+ if (curel < SYSTEM_CUREL_EL1) {
+ LOG_DEBUG("ELR_EL1 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
retval = dpm->instr_write_data_r0_64(dpm,
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;
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;
case ARMV8_ESR_EL1:
- value = value_64;
- retval = dpm->instr_write_data_r0(dpm,
- ARMV8_MSR_GP(SYSTEM_ESR_EL1, 0), value);
+ if (curel < SYSTEM_CUREL_EL1) {
+ LOG_DEBUG("ESR_EL1 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_write_data_r0_64(dpm,
+ ARMV8_MSR_GP(SYSTEM_ESR_EL1, 0), value_64);
break;
case ARMV8_ESR_EL2:
- value = value_64;
- retval = dpm->instr_write_data_r0(dpm,
- ARMV8_MSR_GP(SYSTEM_ESR_EL2, 0), value);
+ if (curel < SYSTEM_CUREL_EL2) {
+ LOG_DEBUG("ESR_EL2 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_write_data_r0_64(dpm,
+ ARMV8_MSR_GP(SYSTEM_ESR_EL2, 0), value_64);
break;
case ARMV8_ESR_EL3:
- value = value_64;
- retval = dpm->instr_write_data_r0(dpm,
- ARMV8_MSR_GP(SYSTEM_ESR_EL3, 0), value);
+ if (curel < SYSTEM_CUREL_EL3) {
+ LOG_DEBUG("ESR_EL3 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_write_data_r0_64(dpm,
+ ARMV8_MSR_GP(SYSTEM_ESR_EL3, 0), value_64);
break;
case ARMV8_SPSR_EL1:
- value = value_64;
- retval = dpm->instr_write_data_r0(dpm,
- ARMV8_MSR_GP(SYSTEM_SPSR_EL1, 0), value);
+ if (curel < SYSTEM_CUREL_EL1) {
+ LOG_DEBUG("SPSR_EL1 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_write_data_r0_64(dpm,
+ ARMV8_MSR_GP(SYSTEM_SPSR_EL1, 0), value_64);
break;
case ARMV8_SPSR_EL2:
- value = value_64;
- retval = dpm->instr_write_data_r0(dpm,
- ARMV8_MSR_GP(SYSTEM_SPSR_EL2, 0), value);
+ if (curel < SYSTEM_CUREL_EL2) {
+ LOG_DEBUG("SPSR_EL2 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_write_data_r0_64(dpm,
+ ARMV8_MSR_GP(SYSTEM_SPSR_EL2, 0), value_64);
break;
case ARMV8_SPSR_EL3:
- value = value_64;
- retval = dpm->instr_write_data_r0(dpm,
- ARMV8_MSR_GP(SYSTEM_SPSR_EL3, 0), value);
+ if (curel < SYSTEM_CUREL_EL3) {
+ LOG_DEBUG("SPSR_EL3 not accessible in EL%u", curel);
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = dpm->instr_write_data_r0_64(dpm,
+ ARMV8_MSR_GP(SYSTEM_SPSR_EL3, 0), value_64);
break;
default:
retval = ERROR_FAIL;
@@ -512,6 +593,9 @@ static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *re
uint32_t value = 0;
int retval;
+ if (!regval)
+ return ERROR_FAIL;
+
switch (regnum) {
case ARMV8_R0 ... ARMV8_R14:
/* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
@@ -559,7 +643,7 @@ static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *re
ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
&value);
break;
- case ARMV8_ESR_EL3: /* FIXME: no equivalent in aarch32? */
+ case ARMV8_ESR_EL3: /* no equivalent in aarch32 */
retval = ERROR_FAIL;
break;
case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */
@@ -587,7 +671,7 @@ static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *re
break;
}
- if (retval == ERROR_OK && regval)
+ if (retval == ERROR_OK)
*regval = value;
return retval;
@@ -695,7 +779,7 @@ static int armv8_write_reg32(struct armv8_common *armv8, int regnum, uint64_t va
ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
value);
break;
- case ARMV8_ESR_EL3: /* FIXME: no equivalent in aarch32? */
+ case ARMV8_ESR_EL3: /* no equivalent in aarch32 */
retval = ERROR_FAIL;
break;
case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */
@@ -1504,23 +1588,23 @@ static const struct {
{ ARMV8_ELR_EL1, "ELR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
NULL},
- { ARMV8_ESR_EL1, "ESR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
+ { ARMV8_ESR_EL1, "ESR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked",
NULL},
- { ARMV8_SPSR_EL1, "SPSR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
+ { ARMV8_SPSR_EL1, "SPSR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked",
NULL},
{ ARMV8_ELR_EL2, "ELR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
NULL},
- { ARMV8_ESR_EL2, "ESR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
+ { ARMV8_ESR_EL2, "ESR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked",
NULL},
- { ARMV8_SPSR_EL2, "SPSR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
+ { ARMV8_SPSR_EL2, "SPSR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked",
NULL},
{ ARMV8_ELR_EL3, "ELR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
NULL},
- { ARMV8_ESR_EL3, "ESR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
+ { ARMV8_ESR_EL3, "ESR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked",
NULL},
- { ARMV8_SPSR_EL3, "SPSR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
+ { ARMV8_SPSR_EL3, "SPSR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked",
NULL},
{ ARMV8_PAUTH_DMASK, "pauth_dmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL},
{ ARMV8_PAUTH_CMASK, "pauth_cmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL},