target-arm/helper.c: define MPUIR register

Define the MPUIR register for MPU supporting ARMv6 and onwards.
Currently we only support unified MPU.

The size of the unified MPU is defined via the number of "dregions".
So just a single config is added to specify this size. (When split MPU
is implemented we will add an extra iregions config).

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 9f248950b803a08c8b3c978931663182f7e882e7.1434501320.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Crosthwaite 2015-06-19 14:17:44 +01:00 committed by Peter Maydell
parent b061a82b8a
commit 3281af8114
3 changed files with 30 additions and 0 deletions

View File

@ -105,6 +105,8 @@ typedef struct ARMCPU {
/* CPU has memory protection unit */ /* CPU has memory protection unit */
bool has_mpu; bool has_mpu;
/* PMSAv7 MPU number of supported regions */
uint32_t pmsav7_dregion;
/* PSCI conduit used to invoke PSCI methods /* PSCI conduit used to invoke PSCI methods
* 0 - disabled, 1 - smc, 2 - hvc * 0 - disabled, 1 - smc, 2 - hvc

View File

@ -457,6 +457,9 @@ static Property arm_cpu_has_el3_property =
static Property arm_cpu_has_mpu_property = static Property arm_cpu_has_mpu_property =
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true); DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
static Property arm_cpu_pmsav7_dregion_property =
DEFINE_PROP_UINT32("pmsav7-dregion", ARMCPU, pmsav7_dregion, 16);
static void arm_cpu_post_init(Object *obj) static void arm_cpu_post_init(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
@ -488,6 +491,11 @@ static void arm_cpu_post_init(Object *obj)
if (arm_feature(&cpu->env, ARM_FEATURE_MPU)) { if (arm_feature(&cpu->env, ARM_FEATURE_MPU)) {
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property, qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
&error_abort); &error_abort);
if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
qdev_property_add_static(DEVICE(obj),
&arm_cpu_pmsav7_dregion_property,
&error_abort);
}
} }
} }
@ -580,6 +588,16 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
unset_feature(env, ARM_FEATURE_MPU); unset_feature(env, ARM_FEATURE_MPU);
} }
if (arm_feature(env, ARM_FEATURE_MPU) &&
arm_feature(env, ARM_FEATURE_V7)) {
uint32_t nr = cpu->pmsav7_dregion;
if (nr > 0xff) {
error_setg(errp, "PMSAv7 MPU #regions invalid %" PRIu32 "\n", nr);
return;
}
}
register_cp_regs_for_features(cpu); register_cp_regs_for_features(cpu);
arm_cpu_register_gdb_regs_for_features(cpu); arm_cpu_register_gdb_regs_for_features(cpu);

View File

@ -3457,6 +3457,13 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3, .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0, .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0,
}; };
/* MPUIR is specific to PMSA V6+ */
ARMCPRegInfo id_mpuir_reginfo = {
.name = "MPUIR",
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = cpu->pmsav7_dregion << 8
};
ARMCPRegInfo crn0_wi_reginfo = { ARMCPRegInfo crn0_wi_reginfo = {
.name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY, .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
@ -3479,6 +3486,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
r->access = PL1_RW; r->access = PL1_RW;
} }
id_tlbtr_reginfo.access = PL1_RW; id_tlbtr_reginfo.access = PL1_RW;
id_tlbtr_reginfo.access = PL1_RW;
} }
if (arm_feature(env, ARM_FEATURE_V8)) { if (arm_feature(env, ARM_FEATURE_V8)) {
define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo); define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo);
@ -3488,6 +3496,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, id_cp_reginfo); define_arm_cp_regs(cpu, id_cp_reginfo);
if (!arm_feature(env, ARM_FEATURE_MPU)) { if (!arm_feature(env, ARM_FEATURE_MPU)) {
define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo); define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
} else if (arm_feature(env, ARM_FEATURE_V7)) {
define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
} }
} }