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