Browse Source

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
jim
Antonio Borneo 4 years ago
parent
commit
b5d2b1224f
4 changed files with 69 additions and 8 deletions
  1. +5
    -0
      src/target/arm.h
  2. +54
    -7
      src/target/armv4_5.c
  3. +1
    -1
      src/target/armv4_5.h
  4. +9
    -0
      src/target/cortex_a.c

+ 5
- 0
src/target/arm.h View File

@@ -47,12 +47,16 @@
* on for example ARM7TDMI cores.
* - ARM_CORE_TYPE_SEC_EXT indicates core has security extensions, thus
* three more registers are shadowed for "Secure Monitor" mode.
* - ARM_CORE_TYPE_VIRT_EXT indicates core has virtualization extensions
* and also security extensions. Additional shadowed registers for
* "Secure Monitor" and "Hypervisor" modes.
* - ARM_CORE_TYPE_M_PROFILE indicates a microcontroller profile core,
* which only shadows SP.
*/
enum arm_core_type {
ARM_CORE_TYPE_STD = -1,
ARM_CORE_TYPE_SEC_EXT = 1,
ARM_CORE_TYPE_VIRT_EXT,
ARM_CORE_TYPE_M_PROFILE,
};

@@ -76,6 +80,7 @@ enum arm_mode {
ARM_MODE_SVC = 19,
ARM_MODE_MON = 22,
ARM_MODE_ABT = 23,
ARM_MODE_HYP = 26,
ARM_MODE_UND = 27,
ARM_MODE_1176_MON = 28,
ARM_MODE_SYS = 31,


+ 54
- 7
src/target/armv4_5.c View File

@@ -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 */


+ 1
- 1
src/target/armv4_5.h View File

@@ -38,7 +38,7 @@
int arm_mode_to_number(enum arm_mode mode);
enum arm_mode armv4_5_number_to_mode(int number);

extern const int armv4_5_core_reg_map[8][17];
extern const int armv4_5_core_reg_map[9][17];

#define ARMV4_5_CORE_REG_MODE(cache, mode, num) \
(cache->reg_list[armv4_5_core_reg_map[arm_mode_to_number(mode)][num]])


+ 9
- 0
src/target/cortex_a.c View File

@@ -2797,6 +2797,15 @@ static int cortex_a_examine_first(struct target *target)
target->coreid);
armv7a->arm.core_type = ARM_CORE_TYPE_SEC_EXT;
}
if (dbg_idpfr1 & 0x0000f000) {
LOG_DEBUG("target->coreid %" PRId32 " has virtualization extensions",
target->coreid);
/*
* overwrite and simplify the checks.
* virtualization extensions require implementation of security extension
*/
armv7a->arm.core_type = ARM_CORE_TYPE_VIRT_EXT;
}

/* Avoid recreating the registers cache */
if (!target_was_examined(target)) {


Loading…
Cancel
Save