aboutsummaryrefslogtreecommitdiff
path: root/src/target/armv4_5.c
diff options
context:
space:
mode:
authorAntonio Borneo <borneo.antonio@gmail.com>2019-06-25 16:01:38 +0200
committerAntonio Borneo <borneo.antonio@gmail.com>2020-03-12 10:11:19 +0000
commitb5d2b1224fed3909aa3314339611ac5ac7ab0f82 (patch)
tree5e38e99cfe6dbdf131b4b452948b3b889b7eac23 /src/target/armv4_5.c
parent6900c5af4ec3f6df52227169d7d897eb14a44bca (diff)
downloadriscv-openocd-b5d2b1224fed3909aa3314339611ac5ac7ab0f82.zip
riscv-openocd-b5d2b1224fed3909aa3314339611ac5ac7ab0f82.tar.gz
riscv-openocd-b5d2b1224fed3909aa3314339611ac5ac7ab0f82.tar.bz2
target/cortex_a: add hypervisor mode
Hypervisor mode is present only if the optional virtualization extensions are available. Moreover, virtualization extensions require that also security extensions are implemented. Add the required infrastructure for the shadowed registers in hypervisor mode. Make monitor shadowed registers visible in hypervisor mode too. Make hypervisor shadowed registers visible in hypervisor mode only. Check during cortex_a examine if virtualization extensions are present and then conditionally enable the visibility of both hypervisor and monitor modes shadowed registers. Change-Id: I81dbb1ee8baf4c9f1a2226b77c10c8a2a7b34871 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/5261 Tested-by: jenkins
Diffstat (limited to 'src/target/armv4_5.c')
-rw-r--r--src/target/armv4_5.c61
1 files changed, 54 insertions, 7 deletions
diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c
index c27e953..a0983cd 100644
--- a/src/target/armv4_5.c
+++ b/src/target/armv4_5.c
@@ -48,6 +48,7 @@ enum {
ARMV4_5_SPSR_ABT = 35,
ARMV4_5_SPSR_UND = 36,
ARM_SPSR_MON = 41,
+ ARM_SPSR_HYP = 43,
};
static const uint8_t arm_usr_indices[17] = {
@@ -78,6 +79,10 @@ static const uint8_t arm_mon_indices[3] = {
39, 40, ARM_SPSR_MON,
};
+static const uint8_t arm_hyp_indices[2] = {
+ 42, ARM_SPSR_HYP,
+};
+
static const struct {
const char *name;
unsigned short psr;
@@ -163,6 +168,14 @@ static const struct {
.name = "Handler",
.psr = ARM_MODE_HANDLER,
},
+
+ /* armv7-a with virtualization extension */
+ {
+ .name = "Hypervisor",
+ .psr = ARM_MODE_HYP,
+ .n_indices = ARRAY_SIZE(arm_hyp_indices),
+ .indices = arm_hyp_indices,
+ },
};
/** Map PSR mode bits to the name of an ARM processor operating mode. */
@@ -209,6 +222,8 @@ int arm_mode_to_number(enum arm_mode mode)
case ARM_MODE_MON:
case ARM_MODE_1176_MON:
return 7;
+ case ARM_MODE_HYP:
+ return 8;
default:
LOG_ERROR("invalid mode value encountered %d", mode);
return -1;
@@ -235,6 +250,8 @@ enum arm_mode armv4_5_number_to_mode(int number)
return ARM_MODE_SYS;
case 7:
return ARM_MODE_MON;
+ case 8:
+ return ARM_MODE_HYP;
default:
LOG_ERROR("mode index out of bounds %d", number);
return ARM_MODE_ANY;
@@ -342,6 +359,9 @@ static const struct {
[40] = { .name = "lr_mon", .cookie = 14, .mode = ARM_MODE_MON, .gdb_index = 49, },
[41] = { .name = "spsr_mon", .cookie = 16, .mode = ARM_MODE_MON, .gdb_index = 50, },
+ /* These exist only when the Virtualization Extensions is present */
+ [42] = { .name = "sp_hyp", .cookie = 13, .mode = ARM_MODE_HYP, .gdb_index = 51, },
+ [43] = { .name = "spsr_hyp", .cookie = 16, .mode = ARM_MODE_HYP, .gdb_index = 52, },
};
static const struct {
@@ -391,7 +411,7 @@ static const struct {
/* map core mode (USR, FIQ, ...) and register number to
* indices into the register cache
*/
-const int armv4_5_core_reg_map[8][17] = {
+const int armv4_5_core_reg_map[9][17] = {
{ /* USR */
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
},
@@ -415,6 +435,9 @@ const int armv4_5_core_reg_map[8][17] = {
},
{ /* MON */
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 39, 40, 15, 41,
+ },
+ { /* HYP */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 42, 14, 15, 43,
}
};
@@ -658,7 +681,11 @@ struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm)
for (i = 0; i < num_core_regs; i++) {
/* Skip registers this core doesn't expose */
if (arm_core_regs[i].mode == ARM_MODE_MON
- && arm->core_type != ARM_CORE_TYPE_SEC_EXT)
+ && arm->core_type != ARM_CORE_TYPE_SEC_EXT
+ && arm->core_type != ARM_CORE_TYPE_VIRT_EXT)
+ continue;
+ if (arm_core_regs[i].mode == ARM_MODE_HYP
+ && arm->core_type != ARM_CORE_TYPE_VIRT_EXT)
continue;
/* REVISIT handle Cortex-M, which only shadows R13/SP */
@@ -816,8 +843,13 @@ COMMAND_HANDLER(handle_armv4_5_reg_command)
name = "System and User";
sep = "";
break;
+ case ARM_MODE_HYP:
+ if (arm->core_type != ARM_CORE_TYPE_VIRT_EXT)
+ continue;
+ /* FALLTHROUGH */
case ARM_MODE_MON:
- if (arm->core_type != ARM_CORE_TYPE_SEC_EXT)
+ if (arm->core_type != ARM_CORE_TYPE_SEC_EXT
+ && arm->core_type != ARM_CORE_TYPE_VIRT_EXT)
continue;
/* FALLTHROUGH */
default:
@@ -1194,7 +1226,16 @@ int arm_get_gdb_reg_list(struct target *target,
break;
case REG_CLASS_ALL:
- *reg_list_size = (arm->core_type != ARM_CORE_TYPE_SEC_EXT ? 48 : 51);
+ switch (arm->core_type) {
+ case ARM_CORE_TYPE_SEC_EXT:
+ *reg_list_size = 51;
+ break;
+ case ARM_CORE_TYPE_VIRT_EXT:
+ *reg_list_size = 53;
+ break;
+ default:
+ *reg_list_size = 48;
+ }
unsigned int list_size_core = *reg_list_size;
if (arm->arm_vfp_version == ARM_VFP_V3)
*reg_list_size += 33;
@@ -1206,9 +1247,15 @@ int arm_get_gdb_reg_list(struct target *target,
for (i = 13; i < ARRAY_SIZE(arm_core_regs); i++) {
int reg_index = arm->core_cache->reg_list[i].number;
- if (!(arm_core_regs[i].mode == ARM_MODE_MON
- && arm->core_type != ARM_CORE_TYPE_SEC_EXT))
- (*reg_list)[reg_index] = &(arm->core_cache->reg_list[i]);
+
+ if (arm_core_regs[i].mode == ARM_MODE_MON
+ && arm->core_type != ARM_CORE_TYPE_SEC_EXT
+ && arm->core_type != ARM_CORE_TYPE_VIRT_EXT)
+ continue;
+ if (arm_core_regs[i].mode == ARM_MODE_HYP
+ && arm->core_type != ARM_CORE_TYPE_VIRT_EXT)
+ continue;
+ (*reg_list)[reg_index] = &(arm->core_cache->reg_list[i]);
}
/* When we supply the target description, there is no need for fake FPA */