* [PATCH v6 0/7] Add ARM Cortex-R52 CPU
@ 2022-12-06 10:24 tobias.roehmel
2022-12-06 10:24 ` [PATCH v6 1/7] target/arm: Don't add all MIDR aliases for cores that implement PMSA tobias.roehmel
` (8 more replies)
0 siblings, 9 replies; 13+ messages in thread
From: tobias.roehmel @ 2022-12-06 10:24 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Sorry for the "Reviewed-by" messup. I missed that on the explanation
page. Thanks again for the review :)
v6:
patch 5:
- I also changed HPRENR from ARM_CP_ALIAS to ARM_CP_NO_RAW.
Its state is also present in the HPRLAR registers,
but it doesn't make sense to access it raw. (I think)
- I'm freeing the PRBAR/... strings explicitly now since
I don't know how to use autofree in this setup correctly.
Maybe {} around the part were the string is created/used,
such that it is dropped at }?
Tobias Röhmel (7):
target/arm: Don't add all MIDR aliases for cores that implement PMSA
target/arm: Make RVBAR available for all ARMv8 CPUs
target/arm: Make stage_2_format for cache attributes optional
target/arm: Enable TTBCR_EAE for ARMv8-R AArch32
target/arm: Add PMSAv8r registers
target/arm: Add PMSAv8r functionality
target/arm: Add ARM Cortex-R52 CPU
target/arm/cpu.c | 34 +++-
target/arm/cpu.h | 6 +
target/arm/cpu_tcg.c | 42 +++++
target/arm/debug_helper.c | 3 +
target/arm/helper.c | 336 ++++++++++++++++++++++++++++++++++++--
target/arm/internals.h | 4 +
target/arm/machine.c | 28 ++++
target/arm/ptw.c | 136 ++++++++++++---
target/arm/tlb_helper.c | 4 +
9 files changed, 553 insertions(+), 40 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 1/7] target/arm: Don't add all MIDR aliases for cores that implement PMSA
2022-12-06 10:24 [PATCH v6 0/7] Add ARM Cortex-R52 CPU tobias.roehmel
@ 2022-12-06 10:24 ` tobias.roehmel
2022-12-06 10:24 ` [PATCH v6 2/7] target/arm: Make RVBAR available for all ARMv8 CPUs tobias.roehmel
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: tobias.roehmel @ 2022-12-06 10:24 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel, Richard Henderson
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Cores with PMSA have the MPUIR register which has the
same encoding as the MIDR alias with opc2=4. So we only
add that alias if we are not realizing a core that
implements PMSA.
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/helper.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d8c8223ec3..d857d61fa9 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8112,10 +8112,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,
.fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
.readfn = midr_read },
- /* crn = 0 op1 = 0 crm = 0 op2 = 4,7 : AArch32 aliases of MIDR */
- { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
- .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
- .access = PL1_R, .resetvalue = cpu->midr },
+ /* crn = 0 op1 = 0 crm = 0 op2 = 7 : AArch32 aliases of MIDR */
{ .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7,
.access = PL1_R, .resetvalue = cpu->midr },
@@ -8125,6 +8122,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.accessfn = access_aa64_tid1,
.type = ARM_CP_CONST, .resetvalue = cpu->revidr },
};
+ ARMCPRegInfo id_v8_midr_alias_cp_reginfo = {
+ .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
+ .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
+ .access = PL1_R, .resetvalue = cpu->midr
+ };
ARMCPRegInfo id_cp_reginfo[] = {
/* These are common to v8 and pre-v8 */
{ .name = "CTR",
@@ -8190,6 +8192,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
}
if (arm_feature(env, ARM_FEATURE_V8)) {
define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo);
+ if (!arm_feature(env, ARM_FEATURE_PMSA)) {
+ define_one_arm_cp_reg(cpu, &id_v8_midr_alias_cp_reginfo);
+ }
} else {
define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v6 2/7] target/arm: Make RVBAR available for all ARMv8 CPUs
2022-12-06 10:24 [PATCH v6 0/7] Add ARM Cortex-R52 CPU tobias.roehmel
2022-12-06 10:24 ` [PATCH v6 1/7] target/arm: Don't add all MIDR aliases for cores that implement PMSA tobias.roehmel
@ 2022-12-06 10:24 ` tobias.roehmel
2022-12-06 10:25 ` [PATCH v6 3/7] target/arm: Make stage_2_format for cache attributes optional tobias.roehmel
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: tobias.roehmel @ 2022-12-06 10:24 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
RVBAR shadows RVBAR_ELx where x is the highest exception
level if the highest EL is not EL3. This patch also allows
ARMv8 CPUs to change the reset address with
the rvbar property.
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/cpu.c | 6 +++++-
target/arm/helper.c | 21 ++++++++++++++-------
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 38d066c294..f9ab6af829 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -307,6 +307,10 @@ static void arm_cpu_reset(DeviceState *dev)
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
CPACR, CP11, 3);
#endif
+ if (arm_feature(env, ARM_FEATURE_V8)) {
+ env->cp15.rvbar = cpu->rvbar_prop;
+ env->regs[15] = cpu->rvbar_prop;
+ }
}
#if defined(CONFIG_USER_ONLY)
@@ -1342,7 +1346,7 @@ void arm_cpu_post_init(Object *obj)
qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property);
}
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
object_property_add_uint64_ptr(obj, "rvbar",
&cpu->rvbar_prop,
OBJ_PROP_FLAG_READWRITE);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d857d61fa9..23a55dbe7d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7855,7 +7855,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
if (!arm_feature(env, ARM_FEATURE_EL3) &&
!arm_feature(env, ARM_FEATURE_EL2)) {
ARMCPRegInfo rvbar = {
- .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64,
+ .name = "RVBAR_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
.access = PL1_R,
.fieldoffset = offsetof(CPUARMState, cp15.rvbar),
@@ -7946,13 +7946,20 @@ void register_cp_regs_for_features(ARMCPU *cpu)
}
/* RVBAR_EL2 is only implemented if EL2 is the highest EL */
if (!arm_feature(env, ARM_FEATURE_EL3)) {
- ARMCPRegInfo rvbar = {
- .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
- .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
- .access = PL2_R,
- .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
+ ARMCPRegInfo rvbar[] = {
+ {
+ .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
+ .access = PL2_R,
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
+ },
+ { .name = "RVBAR", .type = ARM_CP_ALIAS,
+ .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
+ .access = PL2_R,
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
+ },
};
- define_one_arm_cp_reg(cpu, &rvbar);
+ define_arm_cp_regs(cpu, rvbar);
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v6 3/7] target/arm: Make stage_2_format for cache attributes optional
2022-12-06 10:24 [PATCH v6 0/7] Add ARM Cortex-R52 CPU tobias.roehmel
2022-12-06 10:24 ` [PATCH v6 1/7] target/arm: Don't add all MIDR aliases for cores that implement PMSA tobias.roehmel
2022-12-06 10:24 ` [PATCH v6 2/7] target/arm: Make RVBAR available for all ARMv8 CPUs tobias.roehmel
@ 2022-12-06 10:25 ` tobias.roehmel
2022-12-06 10:25 ` [PATCH v6 4/7] target/arm: Enable TTBCR_EAE for ARMv8-R AArch32 tobias.roehmel
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: tobias.roehmel @ 2022-12-06 10:25 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
The v8R PMSAv8 has a two-stage MPU translation process, but, unlike
VMSAv8, the stage 2 attributes are in the same format as the stage 1
attributes (8-bit MAIR format). Rather than converting the MAIR
format to the format used for VMSA stage 2 (bits [5:2] of a VMSA
stage 2 descriptor) and then converting back to do the attribute
combination, allow combined_attrs_nofwb() to accept s2 attributes
that are already in the MAIR format.
We move the assert() to combined_attrs_fwb(), because that function
really does require a VMSA stage 2 attribute format. (We will never
get there for v8R, because PMSAv8 does not implement FEAT_S2FWB.)
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/ptw.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index f812734bfb..7d19829702 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -2361,7 +2361,11 @@ static uint8_t combined_attrs_nofwb(uint64_t hcr,
{
uint8_t s1lo, s2lo, s1hi, s2hi, s2_mair_attrs, ret_attrs;
- s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
+ if (s2.is_s2_format) {
+ s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
+ } else {
+ s2_mair_attrs = s2.attrs;
+ }
s1lo = extract32(s1.attrs, 0, 4);
s2lo = extract32(s2_mair_attrs, 0, 4);
@@ -2418,6 +2422,8 @@ static uint8_t force_cacheattr_nibble_wb(uint8_t attr)
*/
static uint8_t combined_attrs_fwb(ARMCacheAttrs s1, ARMCacheAttrs s2)
{
+ assert(s2.is_s2_format && !s1.is_s2_format);
+
switch (s2.attrs) {
case 7:
/* Use stage 1 attributes */
@@ -2467,7 +2473,7 @@ static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
ARMCacheAttrs ret;
bool tagged = false;
- assert(s2.is_s2_format && !s1.is_s2_format);
+ assert(!s1.is_s2_format);
ret.is_s2_format = false;
if (s1.attrs == 0xf0) {
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v6 4/7] target/arm: Enable TTBCR_EAE for ARMv8-R AArch32
2022-12-06 10:24 [PATCH v6 0/7] Add ARM Cortex-R52 CPU tobias.roehmel
` (2 preceding siblings ...)
2022-12-06 10:25 ` [PATCH v6 3/7] target/arm: Make stage_2_format for cache attributes optional tobias.roehmel
@ 2022-12-06 10:25 ` tobias.roehmel
2022-12-06 10:25 ` [PATCH v6 5/7] target/arm: Add PMSAv8r registers tobias.roehmel
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: tobias.roehmel @ 2022-12-06 10:25 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
ARMv8-R AArch32 CPUs behave as if TTBCR.EAE is always 1 even
tough they don't have the TTBCR register.
See ARM Architecture Reference Manual Supplement - ARMv8, for the ARMv8-R
AArch32 architecture profile Version:A.c section C1.2.
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/debug_helper.c | 3 +++
target/arm/internals.h | 4 ++++
target/arm/tlb_helper.c | 4 ++++
3 files changed, 11 insertions(+)
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
index c21739242c..2f6ddc0da5 100644
--- a/target/arm/debug_helper.c
+++ b/target/arm/debug_helper.c
@@ -437,6 +437,9 @@ static uint32_t arm_debug_exception_fsr(CPUARMState *env)
if (target_el == 2 || arm_el_is_aa64(env, target_el)) {
using_lpae = true;
+ } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
+ arm_feature(env, ARM_FEATURE_V8)) {
+ using_lpae = true;
} else {
if (arm_feature(env, ARM_FEATURE_LPAE) &&
(env->cp15.tcr_el[target_el] & TTBCR_EAE)) {
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 161e42d50f..d9555309df 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -257,6 +257,10 @@ unsigned int arm_pamax(ARMCPU *cpu);
static inline bool extended_addresses_enabled(CPUARMState *env)
{
uint64_t tcr = env->cp15.tcr_el[arm_is_secure(env) ? 3 : 1];
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
+ arm_feature(env, ARM_FEATURE_V8)) {
+ return true;
+ }
return arm_el_is_aa64(env, 1) ||
(arm_feature(env, ARM_FEATURE_LPAE) && (tcr & TTBCR_EAE));
}
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
index 0f4f4fc809..60abcbebe6 100644
--- a/target/arm/tlb_helper.c
+++ b/target/arm/tlb_helper.c
@@ -19,6 +19,10 @@ bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
if (el == 2 || arm_el_is_aa64(env, el)) {
return true;
}
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
+ arm_feature(env, ARM_FEATURE_V8)) {
+ return true;
+ }
if (arm_feature(env, ARM_FEATURE_LPAE)
&& (regime_tcr(env, mmu_idx) & TTBCR_EAE)) {
return true;
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v6 5/7] target/arm: Add PMSAv8r registers
2022-12-06 10:24 [PATCH v6 0/7] Add ARM Cortex-R52 CPU tobias.roehmel
` (3 preceding siblings ...)
2022-12-06 10:25 ` [PATCH v6 4/7] target/arm: Enable TTBCR_EAE for ARMv8-R AArch32 tobias.roehmel
@ 2022-12-06 10:25 ` tobias.roehmel
2022-12-06 10:25 ` [PATCH v6 6/7] target/arm: Add PMSAv8r functionality tobias.roehmel
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: tobias.roehmel @ 2022-12-06 10:25 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
---
target/arm/cpu.c | 28 +++-
target/arm/cpu.h | 6 +
target/arm/helper.c | 302 +++++++++++++++++++++++++++++++++++++++++++
target/arm/machine.c | 28 ++++
4 files changed, 360 insertions(+), 4 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index f9ab6af829..497be4b464 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -489,6 +489,14 @@ static void arm_cpu_reset(DeviceState *dev)
sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
}
}
+
+ if (cpu->pmsav8r_hdregion > 0) {
+ memset(env->pmsav8.hprbar, 0,
+ sizeof(*env->pmsav8.hprbar) * cpu->pmsav8r_hdregion);
+ memset(env->pmsav8.hprlar, 0,
+ sizeof(*env->pmsav8.hprlar) * cpu->pmsav8r_hdregion);
+ }
+
env->pmsav7.rnr[M_REG_NS] = 0;
env->pmsav7.rnr[M_REG_S] = 0;
env->pmsav8.mair0[M_REG_NS] = 0;
@@ -1999,11 +2007,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
* to false or by setting pmsav7-dregion to 0.
*/
- if (!cpu->has_mpu) {
- cpu->pmsav7_dregion = 0;
- }
- if (cpu->pmsav7_dregion == 0) {
+ if (!cpu->has_mpu || cpu->pmsav7_dregion == 0) {
cpu->has_mpu = false;
+ cpu->pmsav7_dregion = 0;
+ cpu->pmsav8r_hdregion = 0;
}
if (arm_feature(env, ARM_FEATURE_PMSA) &&
@@ -2030,6 +2037,19 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
env->pmsav7.dracr = g_new0(uint32_t, nr);
}
}
+
+ if (cpu->pmsav8r_hdregion > 0xff) {
+ error_setg(errp, "PMSAv8 MPU EL2 #regions invalid %" PRIu32,
+ cpu->pmsav8r_hdregion);
+ return;
+ }
+
+ if (cpu->pmsav8r_hdregion) {
+ env->pmsav8.hprbar = g_new0(uint32_t,
+ cpu->pmsav8r_hdregion);
+ env->pmsav8.hprlar = g_new0(uint32_t,
+ cpu->pmsav8r_hdregion);
+ }
}
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9aeed3c848..c2eab52174 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -309,6 +309,7 @@ typedef struct CPUArchState {
};
uint64_t sctlr_el[4];
};
+ uint64_t vsctlr; /* Virtualization System control register. */
uint64_t cpacr_el1; /* Architectural feature access control register */
uint64_t cptr_el[4]; /* ARMv8 feature trap registers */
uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */
@@ -745,8 +746,11 @@ typedef struct CPUArchState {
*/
uint32_t *rbar[M_REG_NUM_BANKS];
uint32_t *rlar[M_REG_NUM_BANKS];
+ uint32_t *hprbar;
+ uint32_t *hprlar;
uint32_t mair0[M_REG_NUM_BANKS];
uint32_t mair1[M_REG_NUM_BANKS];
+ uint32_t hprselr;
} pmsav8;
/* v8M SAU */
@@ -906,6 +910,8 @@ struct ArchCPU {
bool has_mpu;
/* PMSAv7 MPU number of supported regions */
uint32_t pmsav7_dregion;
+ /* PMSAv8 MPU number of supported hyp regions */
+ uint32_t pmsav8r_hdregion;
/* v8M SAU number of supported regions */
uint32_t sau_sregion;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 23a55dbe7d..e930b04970 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3657,6 +3657,222 @@ static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri,
raw_write(env, ri, value);
}
+static void prbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ ARMCPU *cpu = env_archcpu(env);
+
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
+ env->pmsav8.rbar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]] = value;
+}
+
+static uint64_t prbar_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ return env->pmsav8.rbar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]];
+}
+
+static void prlar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ ARMCPU *cpu = env_archcpu(env);
+
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
+ env->pmsav8.rlar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]] = value;
+}
+
+static uint64_t prlar_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ return env->pmsav8.rlar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]];
+}
+
+static void prselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ ARMCPU *cpu = env_archcpu(env);
+
+ /*
+ * Ignore writes that would select not implemented region.
+ * This is architecturally UNPREDICTABLE.
+ */
+ if (value >= cpu->pmsav7_dregion) {
+ return;
+ }
+
+ env->pmsav7.rnr[M_REG_NS] = value;
+}
+
+static void hprbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ ARMCPU *cpu = env_archcpu(env);
+
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
+ env->pmsav8.hprbar[env->pmsav8.hprselr] = value;
+}
+
+static uint64_t hprbar_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ return env->pmsav8.hprbar[env->pmsav8.hprselr];
+}
+
+static void hprlar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ ARMCPU *cpu = env_archcpu(env);
+
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
+ env->pmsav8.hprlar[env->pmsav8.hprselr] = value;
+}
+
+static uint64_t hprlar_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ return env->pmsav8.hprlar[env->pmsav8.hprselr];
+}
+
+static void hprenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ uint32_t n;
+ uint32_t bit;
+ ARMCPU *cpu = env_archcpu(env);
+
+ /* Ignore writes to unimplemented regions */
+ int rmax = MIN(cpu->pmsav8r_hdregion, 32);
+ value &= MAKE_64BIT_MASK(0, rmax);
+
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
+
+ /* Register alias is only valid for first 32 indexes */
+ for (n = 0; n < rmax; ++n) {
+ bit = extract32(value, n, 1);
+ env->pmsav8.hprlar[n] = deposit32(
+ env->pmsav8.hprlar[n], 0, 1, bit);
+ }
+}
+
+static uint64_t hprenr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ uint32_t n;
+ uint32_t result = 0x0;
+ ARMCPU *cpu = env_archcpu(env);
+
+ /* Register alias is only valid for first 32 indexes */
+ for (n = 0; n < MIN(cpu->pmsav8r_hdregion, 32); ++n) {
+ if (env->pmsav8.hprlar[n] & 0x1) {
+ result |= (0x1 << n);
+ }
+ }
+ return result;
+}
+
+static void hprselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ ARMCPU *cpu = env_archcpu(env);
+
+ /*
+ * Ignore writes that would select not implemented region.
+ * This is architecturally UNPREDICTABLE.
+ */
+ if (value >= cpu->pmsav8r_hdregion) {
+ return;
+ }
+
+ env->pmsav8.hprselr = value;
+}
+
+static void pmsav8r_regn_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ ARMCPU *cpu = env_archcpu(env);
+ uint8_t index = (extract32(ri->opc0, 0, 1) << 4) |
+ (extract32(ri->crm, 0, 3) << 1) | extract32(ri->opc2, 2, 1);
+
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
+
+ if (ri->opc1 & 4) {
+ if (index >= cpu->pmsav8r_hdregion) {
+ return;
+ }
+ if (ri->opc2 & 0x1) {
+ env->pmsav8.hprlar[index] = value;
+ } else {
+ env->pmsav8.hprbar[index] = value;
+ }
+ } else {
+ if (index >= cpu->pmsav7_dregion) {
+ return;
+ }
+ if (ri->opc2 & 0x1) {
+ env->pmsav8.rlar[M_REG_NS][index] = value;
+ } else {
+ env->pmsav8.rbar[M_REG_NS][index] = value;
+ }
+ }
+}
+
+static uint64_t pmsav8r_regn_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ ARMCPU *cpu = env_archcpu(env);
+ uint8_t index = (extract32(ri->opc0, 0, 1) << 4) |
+ (extract32(ri->crm, 0, 3) << 1) | extract32(ri->opc2, 2, 1);
+
+ if (ri->opc1 & 4) {
+ if (index >= cpu->pmsav8r_hdregion) {
+ return 0x0;
+ }
+ if (ri->opc2 & 0x1) {
+ return env->pmsav8.hprlar[index];
+ } else {
+ return env->pmsav8.hprbar[index];
+ }
+ } else {
+ if (index >= cpu->pmsav7_dregion) {
+ return 0x0;
+ }
+ if (ri->opc2 & 0x1) {
+ return env->pmsav8.rlar[M_REG_NS][index];
+ } else {
+ return env->pmsav8.rbar[M_REG_NS][index];
+ }
+ }
+}
+
+static const ARMCPRegInfo pmsav8r_cp_reginfo[] = {
+ { .name = "PRBAR",
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 0,
+ .access = PL1_RW, .type = ARM_CP_NO_RAW,
+ .accessfn = access_tvm_trvm,
+ .readfn = prbar_read, .writefn = prbar_write },
+ { .name = "PRLAR",
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 1,
+ .access = PL1_RW, .type = ARM_CP_NO_RAW,
+ .accessfn = access_tvm_trvm,
+ .readfn = prlar_read, .writefn = prlar_write },
+ { .name = "PRSELR", .resetvalue = 0,
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 2, .opc2 = 1,
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
+ .writefn = prselr_write,
+ .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]) },
+ { .name = "HPRBAR", .resetvalue = 0,
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 0,
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
+ .readfn = hprbar_read, .writefn = hprbar_write },
+ { .name = "HPRLAR",
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 1,
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
+ .readfn = hprlar_read, .writefn = hprlar_write },
+ { .name = "HPRSELR", .resetvalue = 0,
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 2, .opc2 = 1,
+ .access = PL2_RW,
+ .writefn = hprselr_write,
+ .fieldoffset = offsetof(CPUARMState, pmsav8.hprselr) },
+ { .name = "HPRENR",
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 1, .opc2 = 1,
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
+ .readfn = hprenr_read, .writefn = hprenr_write },
+};
+
static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
/* Reset for all these registers is handled in arm_cpu_reset(),
* because the PMSAv7 is also used by M-profile CPUs, which do
@@ -8166,6 +8382,13 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = cpu->pmsav7_dregion << 8
};
+ /* HMPUIR is specific to PMSA V8 */
+ ARMCPRegInfo id_hmpuir_reginfo = {
+ .name = "HMPUIR",
+ .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 4,
+ .access = PL2_R, .type = ARM_CP_CONST,
+ .resetvalue = cpu->pmsav8r_hdregion
+ };
static const ARMCPRegInfo crn0_wi_reginfo = {
.name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
@@ -8208,6 +8431,74 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, id_cp_reginfo);
if (!arm_feature(env, ARM_FEATURE_PMSA)) {
define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
+ } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
+ arm_feature(env, ARM_FEATURE_V8)) {
+ uint32_t i = 0;
+ char *tmp_string;
+
+ define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
+ define_one_arm_cp_reg(cpu, &id_hmpuir_reginfo);
+ define_arm_cp_regs(cpu, pmsav8r_cp_reginfo);
+
+ /* Register alias is only valid for first 32 indexes */
+ for (i = 0; i < MIN(cpu->pmsav7_dregion, 32); ++i) {
+ uint8_t crm = 0b1000 | extract32(i, 1, 3);
+ uint8_t opc1 = extract32(i, 4, 1);
+ uint8_t opc2 = extract32(i, 0, 1) << 2;
+
+ tmp_string = g_strdup_printf("PRBAR%u", i);
+ ARMCPRegInfo tmp_prbarn_reginfo = {
+ .name = tmp_string, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
+ .access = PL1_RW, .resetvalue = 0,
+ .accessfn = access_tvm_trvm,
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
+ };
+ define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo);
+ g_free(tmp_string);
+
+ opc2 = extract32(i, 0, 1) << 2 | 0x1;
+ tmp_string = g_strdup_printf("PRLAR%u", i);
+ ARMCPRegInfo tmp_prlarn_reginfo = {
+ .name = tmp_string, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
+ .access = PL1_RW, .resetvalue = 0,
+ .accessfn = access_tvm_trvm,
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
+ };
+ define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo);
+ g_free(tmp_string);
+ }
+
+ /* Register alias is only valid for first 32 indexes */
+ for (i = 0; i < MIN(cpu->pmsav8r_hdregion, 32); ++i) {
+ uint8_t crm = 0b1000 | extract32(i, 1, 3);
+ uint8_t opc1 = 0b100 | extract32(i, 4, 1);
+ uint8_t opc2 = extract32(i, 0, 1) << 2;
+
+ tmp_string = g_strdup_printf("HPRBAR%u", i);
+ ARMCPRegInfo tmp_hprbarn_reginfo = {
+ .name = tmp_string,
+ .type = ARM_CP_NO_RAW,
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
+ .access = PL2_RW, .resetvalue = 0,
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
+ };
+ define_one_arm_cp_reg(cpu, &tmp_hprbarn_reginfo);
+ g_free(tmp_string);
+
+ opc2 = extract32(i, 0, 1) << 2 | 0x1;
+ tmp_string = g_strdup_printf("HPRLAR%u", i);
+ ARMCPRegInfo tmp_hprlarn_reginfo = {
+ .name = tmp_string,
+ .type = ARM_CP_NO_RAW,
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
+ .access = PL2_RW, .resetvalue = 0,
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
+ };
+ define_one_arm_cp_reg(cpu, &tmp_hprlarn_reginfo);
+ g_free(tmp_string);
+ }
} else if (arm_feature(env, ARM_FEATURE_V7)) {
define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
}
@@ -8329,6 +8620,17 @@ void register_cp_regs_for_features(ARMCPU *cpu)
sctlr.type |= ARM_CP_SUPPRESS_TB_END;
}
define_one_arm_cp_reg(cpu, &sctlr);
+
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
+ arm_feature(env, ARM_FEATURE_V8)) {
+ ARMCPRegInfo vsctlr = {
+ .name = "VSCTLR", .state = ARM_CP_STATE_AA32,
+ .cp = 15, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
+ .access = PL2_RW, .resetvalue = 0x0,
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.vsctlr),
+ };
+ define_one_arm_cp_reg(cpu, &vsctlr);
+ }
}
if (cpu_isar_feature(aa64_lor, cpu)) {
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 54c5c62433..5f26152652 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -487,6 +487,30 @@ static bool pmsav8_needed(void *opaque)
arm_feature(env, ARM_FEATURE_V8);
}
+static bool pmsav8r_needed(void *opaque)
+{
+ ARMCPU *cpu = opaque;
+ CPUARMState *env = &cpu->env;
+
+ return arm_feature(env, ARM_FEATURE_PMSA) &&
+ arm_feature(env, ARM_FEATURE_V8) &&
+ !arm_feature(env, ARM_FEATURE_M);
+}
+
+static const VMStateDescription vmstate_pmsav8r = {
+ .name = "cpu/pmsav8/pmsav8r",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = pmsav8r_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_VARRAY_UINT32(env.pmsav8.hprbar, ARMCPU,
+ pmsav8r_hdregion, 0, vmstate_info_uint32, uint32_t),
+ VMSTATE_VARRAY_UINT32(env.pmsav8.hprlar, ARMCPU,
+ pmsav8r_hdregion, 0, vmstate_info_uint32, uint32_t),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
static const VMStateDescription vmstate_pmsav8 = {
.name = "cpu/pmsav8",
.version_id = 1,
@@ -500,6 +524,10 @@ static const VMStateDescription vmstate_pmsav8 = {
VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (const VMStateDescription * []) {
+ &vmstate_pmsav8r,
+ NULL
}
};
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v6 6/7] target/arm: Add PMSAv8r functionality
2022-12-06 10:24 [PATCH v6 0/7] Add ARM Cortex-R52 CPU tobias.roehmel
` (4 preceding siblings ...)
2022-12-06 10:25 ` [PATCH v6 5/7] target/arm: Add PMSAv8r registers tobias.roehmel
@ 2022-12-06 10:25 ` tobias.roehmel
2022-12-06 10:25 ` [PATCH v6 7/7] target/arm: Add ARM Cortex-R52 CPU tobias.roehmel
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: tobias.roehmel @ 2022-12-06 10:25 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Add PMSAv8r translation.
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/ptw.c | 126 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 104 insertions(+), 22 deletions(-)
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 7d19829702..49e5e5627b 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -1758,9 +1758,13 @@ static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
if (arm_feature(env, ARM_FEATURE_M)) {
return env->v7m.mpu_ctrl[is_secure] & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
- } else {
- return regime_sctlr(env, mmu_idx) & SCTLR_BR;
}
+
+ if (mmu_idx == ARMMMUIdx_Stage2) {
+ return false;
+ }
+
+ return regime_sctlr(env, mmu_idx) & SCTLR_BR;
}
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
@@ -1952,6 +1956,26 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
return !(result->f.prot & (1 << access_type));
}
+static uint32_t *regime_rbar(CPUARMState *env, ARMMMUIdx mmu_idx,
+ uint32_t secure)
+{
+ if (regime_el(env, mmu_idx) == 2) {
+ return env->pmsav8.hprbar;
+ } else {
+ return env->pmsav8.rbar[secure];
+ }
+}
+
+static uint32_t *regime_rlar(CPUARMState *env, ARMMMUIdx mmu_idx,
+ uint32_t secure)
+{
+ if (regime_el(env, mmu_idx) == 2) {
+ return env->pmsav8.hprlar;
+ } else {
+ return env->pmsav8.rlar[secure];
+ }
+}
+
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
MMUAccessType access_type, ARMMMUIdx mmu_idx,
bool secure, GetPhysAddrResult *result,
@@ -1974,6 +1998,13 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
bool hit = false;
uint32_t addr_page_base = address & TARGET_PAGE_MASK;
uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
+ int region_counter;
+
+ if (regime_el(env, mmu_idx) == 2) {
+ region_counter = cpu->pmsav8r_hdregion;
+ } else {
+ region_counter = cpu->pmsav7_dregion;
+ }
result->f.lg_page_size = TARGET_PAGE_BITS;
result->f.phys_addr = address;
@@ -1982,6 +2013,10 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
*mregion = -1;
}
+ if (mmu_idx == ARMMMUIdx_Stage2) {
+ fi->stage2 = true;
+ }
+
/*
* Unlike the ARM ARM pseudocode, we don't need to check whether this
* was an exception vector read from the vector table (which is always
@@ -1998,17 +2033,26 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
hit = true;
}
- for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
+ uint32_t bitmask;
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ bitmask = 0x1f;
+ } else {
+ bitmask = 0x3f;
+ fi->level = 0;
+ }
+
+ for (n = region_counter - 1; n >= 0; n--) {
/* region search */
/*
- * Note that the base address is bits [31:5] from the register
- * with bits [4:0] all zeroes, but the limit address is bits
- * [31:5] from the register with bits [4:0] all ones.
+ * Note that the base address is bits [31:x] from the register
+ * with bits [x-1:0] all zeroes, but the limit address is bits
+ * [31:x] from the register with bits [x:0] all ones. Where x is
+ * 5 for Cortex-M and 6 for Cortex-R
*/
- uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
- uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
+ uint32_t base = regime_rbar(env, mmu_idx, secure)[n] & ~bitmask;
+ uint32_t limit = regime_rlar(env, mmu_idx, secure)[n] | bitmask;
- if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
+ if (!(regime_rlar(env, mmu_idx, secure)[n] & 0x1)) {
/* Region disabled */
continue;
}
@@ -2042,7 +2086,9 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
* PMSAv7 where highest-numbered-region wins)
*/
fi->type = ARMFault_Permission;
- fi->level = 1;
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ fi->level = 1;
+ }
return true;
}
@@ -2052,8 +2098,11 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
}
if (!hit) {
- /* background fault */
- fi->type = ARMFault_Background;
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ fi->type = ARMFault_Background;
+ } else {
+ fi->type = ARMFault_Permission;
+ }
return true;
}
@@ -2061,12 +2110,14 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
/* hit using the background region */
get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot);
} else {
- uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
- uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
+ uint32_t matched_rbar = regime_rbar(env, mmu_idx, secure)[matchregion];
+ uint32_t matched_rlar = regime_rlar(env, mmu_idx, secure)[matchregion];
+ uint32_t ap = extract32(matched_rbar, 1, 2);
+ uint32_t xn = extract32(matched_rbar, 0, 1);
bool pxn = false;
if (arm_feature(env, ARM_FEATURE_V8_1M)) {
- pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
+ pxn = extract32(matched_rlar, 4, 1);
}
if (m_is_system_region(env, address)) {
@@ -2074,21 +2125,46 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
xn = 1;
}
- result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
+ if (regime_el(env, mmu_idx) == 2) {
+ result->f.prot = simple_ap_to_rw_prot_is_user(ap,
+ mmu_idx != ARMMMUIdx_E2);
+ } else {
+ result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
+ }
+
+ if (!arm_feature(env, ARM_FEATURE_M)) {
+ uint8_t attrindx = extract32(matched_rlar, 1, 3);
+ uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
+ uint8_t sh = extract32(matched_rlar, 3, 2);
+
+ if (regime_sctlr(env, mmu_idx) & SCTLR_WXN &&
+ result->f.prot & PAGE_WRITE && mmu_idx != ARMMMUIdx_Stage2) {
+ xn = 0x1;
+ }
+
+ if ((regime_el(env, mmu_idx) == 1) &&
+ regime_sctlr(env, mmu_idx) & SCTLR_UWXN && ap == 0x1) {
+ pxn = 0x1;
+ }
+
+ result->cacheattrs.is_s2_format = false;
+ result->cacheattrs.attrs = extract64(mair, attrindx * 8, 8);
+ result->cacheattrs.shareability = sh;
+ }
+
if (result->f.prot && !xn && !(pxn && !is_user)) {
result->f.prot |= PAGE_EXEC;
}
- /*
- * We don't need to look the attribute up in the MAIR0/MAIR1
- * registers because that only tells us about cacheability.
- */
+
if (mregion) {
*mregion = matchregion;
}
}
fi->type = ARMFault_Permission;
- fi->level = 1;
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ fi->level = 1;
+ }
return !(result->f.prot & (1 << access_type));
}
@@ -2649,7 +2725,13 @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
cacheattrs1 = result->cacheattrs;
memset(result, 0, sizeof(*result));
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type, is_el0, result, fi);
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
+ ret = get_phys_addr_pmsav8(env, ipa, access_type,
+ ptw->in_mmu_idx, is_secure, result, fi);
+ } else {
+ ret = get_phys_addr_lpae(env, ptw, ipa, access_type,
+ is_el0, result, fi);
+ }
fi->s2addr = ipa;
/* Combine the S1 and S2 perms. */
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v6 7/7] target/arm: Add ARM Cortex-R52 CPU
2022-12-06 10:24 [PATCH v6 0/7] Add ARM Cortex-R52 CPU tobias.roehmel
` (5 preceding siblings ...)
2022-12-06 10:25 ` [PATCH v6 6/7] target/arm: Add PMSAv8r functionality tobias.roehmel
@ 2022-12-06 10:25 ` tobias.roehmel
2022-12-06 10:39 ` [PATCH v6 0/7] " Philippe Mathieu-Daudé
2022-12-19 17:05 ` Peter Maydell
8 siblings, 0 replies; 13+ messages in thread
From: tobias.roehmel @ 2022-12-06 10:25 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
All constants are taken from the ARM Cortex-R52 Processor TRM Revision: r1p3
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/cpu_tcg.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 9a2cef7d05..a9e407ccf3 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -853,6 +853,47 @@ static void cortex_r5_initfn(Object *obj)
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
}
+static void cortex_r52_initfn(Object *obj)
+{
+ ARMCPU *cpu = ARM_CPU(obj);
+
+ set_feature(&cpu->env, ARM_FEATURE_V8);
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
+ set_feature(&cpu->env, ARM_FEATURE_PMSA);
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
+ cpu->midr = 0x411fd133; /* r1p3 */
+ cpu->revidr = 0x00000000;
+ cpu->reset_fpsid = 0x41034023;
+ cpu->isar.mvfr0 = 0x10110222;
+ cpu->isar.mvfr1 = 0x12111111;
+ cpu->isar.mvfr2 = 0x00000043;
+ cpu->ctr = 0x8144c004;
+ cpu->reset_sctlr = 0x30c50838;
+ cpu->isar.id_pfr0 = 0x00000131;
+ cpu->isar.id_pfr1 = 0x10111001;
+ cpu->isar.id_dfr0 = 0x03010006;
+ cpu->id_afr0 = 0x00000000;
+ cpu->isar.id_mmfr0 = 0x00211040;
+ cpu->isar.id_mmfr1 = 0x40000000;
+ cpu->isar.id_mmfr2 = 0x01200000;
+ cpu->isar.id_mmfr3 = 0xf0102211;
+ cpu->isar.id_mmfr4 = 0x00000010;
+ cpu->isar.id_isar0 = 0x02101110;
+ cpu->isar.id_isar1 = 0x13112111;
+ cpu->isar.id_isar2 = 0x21232142;
+ cpu->isar.id_isar3 = 0x01112131;
+ cpu->isar.id_isar4 = 0x00010142;
+ cpu->isar.id_isar5 = 0x00010001;
+ cpu->isar.dbgdidr = 0x77168000;
+ cpu->clidr = (1 << 27) | (1 << 24) | 0x3;
+ cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
+ cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
+
+ cpu->pmsav7_dregion = 16;
+ cpu->pmsav8r_hdregion = 16;
+}
+
static void cortex_r5f_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
@@ -1162,6 +1203,7 @@ static const ARMCPUInfo arm_tcg_cpus[] = {
.class_init = arm_v7m_class_init },
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
+ { .name = "cortex-r52", .initfn = cortex_r52_initfn },
{ .name = "ti925t", .initfn = ti925t_initfn },
{ .name = "sa1100", .initfn = sa1100_initfn },
{ .name = "sa1110", .initfn = sa1110_initfn },
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v6 0/7] Add ARM Cortex-R52 CPU
2022-12-06 10:24 [PATCH v6 0/7] Add ARM Cortex-R52 CPU tobias.roehmel
` (6 preceding siblings ...)
2022-12-06 10:25 ` [PATCH v6 7/7] target/arm: Add ARM Cortex-R52 CPU tobias.roehmel
@ 2022-12-06 10:39 ` Philippe Mathieu-Daudé
2022-12-06 11:43 ` Tobias Roehmel
2022-12-19 17:05 ` Peter Maydell
8 siblings, 1 reply; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2022-12-06 10:39 UTC (permalink / raw)
To: tobias.roehmel, qemu-devel; +Cc: peter.maydell
On 6/12/22 11:24, tobias.roehmel@rwth-aachen.de wrote:
> From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
> v6:
> patch 5:
> - I'm freeing the PRBAR/... strings explicitly now since
> I don't know how to use autofree in this setup correctly.
> Maybe {} around the part were the string is created/used,
> such that it is dropped at }?
The pointer is declared outside of a for() statement. Then
inside this statement you alloc/free twice, using the same
pointer. This is correct. If you really want to use
g_autofree in such case, you'd need to declare within the
same statement, one pointer for each string:
for (i = 0; i < MIN(cpu->pmsav7_dregion, 32); ++i) {
uint8_t crm = 0b1000 | extract32(i, 1, 3);
uint8_t opc1 = extract32(i, 4, 1);
uint8_t opc2 = extract32(i, 0, 1) << 2;
g_autofree char *prbarn_str = g_strdup_printf("PRBAR%u", i);
g_autofree char *prlarn_str = g_strdup_printf("PRLAR%u", i);
const ARMCPRegInfo tmp_prbarn_reginfo = {
.name = prbarn_str, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
.cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
.access = PL1_RW, .resetvalue = 0,
.accessfn = access_tvm_trvm,
.writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
};
define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo);
opc2 = extract32(i, 0, 1) << 2 | 0x1;
const ARMCPRegInfo tmp_prlarn_reginfo = {
.name = prlarn_str, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
.cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
.access = PL1_RW, .resetvalue = 0,
.accessfn = access_tvm_trvm,
.writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
};
define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo);
}
(Note ARMCPRegInfo can be qualified const).
Regards,
Phil.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 0/7] Add ARM Cortex-R52 CPU
2022-12-06 10:39 ` [PATCH v6 0/7] " Philippe Mathieu-Daudé
@ 2022-12-06 11:43 ` Tobias Roehmel
2022-12-06 12:00 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 13+ messages in thread
From: Tobias Roehmel @ 2022-12-06 11:43 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel; +Cc: peter.maydell
On 06.12.22 11:39, Philippe Mathieu-Daudé wrote:
> On 6/12/22 11:24, tobias.roehmel@rwth-aachen.de wrote:
>> From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
>
>> v6:
>> patch 5:
>> - I'm freeing the PRBAR/... strings explicitly now since
>> I don't know how to use autofree in this setup correctly.
>> Maybe {} around the part were the string is created/used,
>> such that it is dropped at }?
>
> The pointer is declared outside of a for() statement. Then
> inside this statement you alloc/free twice, using the same
> pointer. This is correct. If you really want to use
> g_autofree in such case, you'd need to declare within the
> same statement, one pointer for each string:
>
> for (i = 0; i < MIN(cpu->pmsav7_dregion, 32); ++i) {
> uint8_t crm = 0b1000 | extract32(i, 1, 3);
> uint8_t opc1 = extract32(i, 4, 1);
> uint8_t opc2 = extract32(i, 0, 1) << 2;
> g_autofree char *prbarn_str = g_strdup_printf("PRBAR%u", i);
> g_autofree char *prlarn_str = g_strdup_printf("PRLAR%u", i);
>
> const ARMCPRegInfo tmp_prbarn_reginfo = {
> .name = prbarn_str, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
> .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
> .access = PL1_RW, .resetvalue = 0,
> .accessfn = access_tvm_trvm,
> .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
> };
> define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo);
>
> opc2 = extract32(i, 0, 1) << 2 | 0x1;
> const ARMCPRegInfo tmp_prlarn_reginfo = {
> .name = prlarn_str, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
> .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
> .access = PL1_RW, .resetvalue = 0,
> .accessfn = access_tvm_trvm,
> .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
> };
> define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo);
> }
>
> (Note ARMCPRegInfo can be qualified const).
>
> Regards,
>
> Phil.
Thanks for the explanation! Would that be the preferred way?
Best regards,
Tobias
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 0/7] Add ARM Cortex-R52 CPU
2022-12-06 11:43 ` Tobias Roehmel
@ 2022-12-06 12:00 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2022-12-06 12:00 UTC (permalink / raw)
To: Tobias Roehmel, qemu-devel; +Cc: peter.maydell, Daniel P. Berrangé
On 6/12/22 12:43, Tobias Roehmel wrote:
>
> On 06.12.22 11:39, Philippe Mathieu-Daudé wrote:
>> On 6/12/22 11:24, tobias.roehmel@rwth-aachen.de wrote:
>>> From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
>>
>>> v6:
>>> patch 5:
>>> - I'm freeing the PRBAR/... strings explicitly now since
>>> I don't know how to use autofree in this setup correctly.
>>> Maybe {} around the part were the string is created/used,
>>> such that it is dropped at }?
>>
>> The pointer is declared outside of a for() statement. Then
>> inside this statement you alloc/free twice, using the same
>> pointer. This is correct. If you really want to use
>> g_autofree in such case, you'd need to declare within the
>> same statement, one pointer for each string:
>>
>> for (i = 0; i < MIN(cpu->pmsav7_dregion, 32); ++i) {
>> uint8_t crm = 0b1000 | extract32(i, 1, 3);
>> uint8_t opc1 = extract32(i, 4, 1);
>> uint8_t opc2 = extract32(i, 0, 1) << 2;
>> g_autofree char *prbarn_str = g_strdup_printf("PRBAR%u", i);
>> g_autofree char *prlarn_str = g_strdup_printf("PRLAR%u", i);
>>
>> const ARMCPRegInfo tmp_prbarn_reginfo = {
>> .name = prbarn_str, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
>> .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
>> .access = PL1_RW, .resetvalue = 0,
>> .accessfn = access_tvm_trvm,
>> .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
>> };
>> define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo);
>>
>> opc2 = extract32(i, 0, 1) << 2 | 0x1;
>> const ARMCPRegInfo tmp_prlarn_reginfo = {
>> .name = prlarn_str, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
>> .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
>> .access = PL1_RW, .resetvalue = 0,
>> .accessfn = access_tvm_trvm,
>> .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
>> };
>> define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo);
>> }
>>
>> (Note ARMCPRegInfo can be qualified const).
>>
>> Regards,
>>
>> Phil.
>
> Thanks for the explanation! Would that be the preferred way?
What you posted is good enough IMO :) AFAIK there is no formal style
recommendation on using g_autofree.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 0/7] Add ARM Cortex-R52 CPU
2022-12-06 10:24 [PATCH v6 0/7] Add ARM Cortex-R52 CPU tobias.roehmel
` (7 preceding siblings ...)
2022-12-06 10:39 ` [PATCH v6 0/7] " Philippe Mathieu-Daudé
@ 2022-12-19 17:05 ` Peter Maydell
2022-12-27 7:34 ` Tobias Röhmel
8 siblings, 1 reply; 13+ messages in thread
From: Peter Maydell @ 2022-12-19 17:05 UTC (permalink / raw)
To: tobias.roehmel; +Cc: qemu-devel
On Tue, 6 Dec 2022 at 10:25, <tobias.roehmel@rwth-aachen.de> wrote:
>
> From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
>
> Sorry for the "Reviewed-by" messup. I missed that on the explanation
> page. Thanks again for the review :)
>
> v6:
> patch 5:
> - I also changed HPRENR from ARM_CP_ALIAS to ARM_CP_NO_RAW.
> Its state is also present in the HPRLAR registers,
> but it doesn't make sense to access it raw. (I think)
> - I'm freeing the PRBAR/... strings explicitly now since
> I don't know how to use autofree in this setup correctly.
> Maybe {} around the part were the string is created/used,
> such that it is dropped at }?
>
Applied to target-arm.next; thanks for your efforts in getting
this patchset through the code review process.
-- PMM
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 0/7] Add ARM Cortex-R52 CPU
2022-12-19 17:05 ` Peter Maydell
@ 2022-12-27 7:34 ` Tobias Röhmel
0 siblings, 0 replies; 13+ messages in thread
From: Tobias Röhmel @ 2022-12-27 7:34 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel
Thanks for all the help, I learned a lot!
Best regards,
Tobias
On 19.12.22 18:05, Peter Maydell wrote:
> On Tue, 6 Dec 2022 at 10:25, <tobias.roehmel@rwth-aachen.de> wrote:
>> From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
>>
>> Sorry for the "Reviewed-by" messup. I missed that on the explanation
>> page. Thanks again for the review :)
>>
>> v6:
>> patch 5:
>> - I also changed HPRENR from ARM_CP_ALIAS to ARM_CP_NO_RAW.
>> Its state is also present in the HPRLAR registers,
>> but it doesn't make sense to access it raw. (I think)
>> - I'm freeing the PRBAR/... strings explicitly now since
>> I don't know how to use autofree in this setup correctly.
>> Maybe {} around the part were the string is created/used,
>> such that it is dropped at }?
>>
> Applied to target-arm.next; thanks for your efforts in getting
> this patchset through the code review process.
>
> -- PMM
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2022-12-27 7:35 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-06 10:24 [PATCH v6 0/7] Add ARM Cortex-R52 CPU tobias.roehmel
2022-12-06 10:24 ` [PATCH v6 1/7] target/arm: Don't add all MIDR aliases for cores that implement PMSA tobias.roehmel
2022-12-06 10:24 ` [PATCH v6 2/7] target/arm: Make RVBAR available for all ARMv8 CPUs tobias.roehmel
2022-12-06 10:25 ` [PATCH v6 3/7] target/arm: Make stage_2_format for cache attributes optional tobias.roehmel
2022-12-06 10:25 ` [PATCH v6 4/7] target/arm: Enable TTBCR_EAE for ARMv8-R AArch32 tobias.roehmel
2022-12-06 10:25 ` [PATCH v6 5/7] target/arm: Add PMSAv8r registers tobias.roehmel
2022-12-06 10:25 ` [PATCH v6 6/7] target/arm: Add PMSAv8r functionality tobias.roehmel
2022-12-06 10:25 ` [PATCH v6 7/7] target/arm: Add ARM Cortex-R52 CPU tobias.roehmel
2022-12-06 10:39 ` [PATCH v6 0/7] " Philippe Mathieu-Daudé
2022-12-06 11:43 ` Tobias Roehmel
2022-12-06 12:00 ` Philippe Mathieu-Daudé
2022-12-19 17:05 ` Peter Maydell
2022-12-27 7:34 ` Tobias Röhmel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.