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] = {
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;
.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. */
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;
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;
[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 {
/* 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
},
},
{ /* 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,
}
};
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 */
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:
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;
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 */