[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 05/14] target/arm: Implement new FEAT_ECV trap bits
From: |
Peter Maydell |
Subject: |
[PULL 05/14] target/arm: Implement new FEAT_ECV trap bits |
Date: |
Fri, 8 Mar 2024 15:50:06 +0000 |
The functionality defined by ID_AA64MMFR0_EL1.ECV == 1 is:
* four new trap bits for various counter and timer registers
* the CNTHCTL_EL2.EVNTIS and CNTKCTL_EL1.EVNTIS bits which control
scaling of the event stream. This is a no-op for us, because we don't
implement the event stream (our WFE is a NOP): all we need to do is
allow CNTHCTL_EL2.ENVTIS to be read and written.
* extensions to PMSCR_EL1.PCT, PMSCR_EL2.PCT, TRFCR_EL1.TS and
TRFCR_EL2.TS: these are all no-ops for us, because we don't implement
FEAT_SPE or FEAT_TRF.
* new registers CNTPCTSS_EL0 and NCTVCTSS_EL0 which are
"self-sychronizing" views of the CNTPCT_EL0 and CNTVCT_EL0, meaning
that no barriers are needed around their accesses. For us these
are just the same as the normal views, because all our sysregs are
inherently self-sychronizing.
In this commit we implement the trap handling and permit the new
CNTHCTL_EL2 bits to be written.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240301183219.2424889-6-peter.maydell@linaro.org
---
target/arm/cpu-features.h | 5 ++++
target/arm/helper.c | 51 +++++++++++++++++++++++++++++++++++----
2 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 7567854db63..b447ec5c0e6 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -741,6 +741,11 @@ static inline bool isar_feature_aa64_fgt(const
ARMISARegisters *id)
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
}
+static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0;
+}
+
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 37845218527..46e0c3c4fcc 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2530,6 +2530,11 @@ static CPAccessResult gt_counter_access(CPUARMState
*env, int timeridx,
: !extract32(env->cp15.cnthctl_el2, 0, 1))) {
return CP_ACCESS_TRAP_EL2;
}
+ if (has_el2 && timeridx == GTIMER_VIRT) {
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1TVCT)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ }
break;
}
return CP_ACCESS_OK;
@@ -2573,6 +2578,11 @@ static CPAccessResult gt_timer_access(CPUARMState *env,
int timeridx,
}
}
}
+ if (has_el2 && timeridx == GTIMER_VIRT) {
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1TVT)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ }
break;
}
return CP_ACCESS_OK;
@@ -2982,6 +2992,14 @@ static void gt_cnthctl_write(CPUARMState *env, const
ARMCPRegInfo *ri,
if (cpu_isar_feature(aa64_rme, cpu)) {
valid_mask |= R_CNTHCTL_CNTVMASK_MASK | R_CNTHCTL_CNTPMASK_MASK;
}
+ if (cpu_isar_feature(aa64_ecv_traps, cpu)) {
+ valid_mask |=
+ R_CNTHCTL_EL1TVT_MASK |
+ R_CNTHCTL_EL1TVCT_MASK |
+ R_CNTHCTL_EL1NVPCT_MASK |
+ R_CNTHCTL_EL1NVVCT_MASK |
+ R_CNTHCTL_EVNTIS_MASK;
+ }
/* Clear RES0 bits */
value &= valid_mask;
@@ -6564,7 +6582,6 @@ static CPAccessResult e2h_access(CPUARMState *env, const
ARMCPRegInfo *ri,
{
if (arm_current_el(env) == 1) {
/* This must be a FEAT_NV access */
- /* TODO: FEAT_ECV will need to check CNTHCTL_EL2 here */
return CP_ACCESS_OK;
}
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
@@ -6573,6 +6590,30 @@ static CPAccessResult e2h_access(CPUARMState *env, const
ARMCPRegInfo *ri,
return CP_ACCESS_OK;
}
+static CPAccessResult access_el1nvpct(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+ if (arm_current_el(env) == 1) {
+ /* This must be a FEAT_NV access with NVx == 101 */
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1NVPCT)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ }
+ return e2h_access(env, ri, isread);
+}
+
+static CPAccessResult access_el1nvvct(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+ if (arm_current_el(env) == 1) {
+ /* This must be a FEAT_NV access with NVx == 101 */
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1NVVCT)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ }
+ return e2h_access(env, ri, isread);
+}
+
/* Test if system register redirection is to occur in the current state. */
static bool redirect_for_e2h(CPUARMState *env)
{
@@ -8398,14 +8439,14 @@ static const ARMCPRegInfo vhe_reginfo[] = {
{ .name = "CNTP_CTL_EL02", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 1,
.type = ARM_CP_IO | ARM_CP_ALIAS,
- .access = PL2_RW, .accessfn = e2h_access,
+ .access = PL2_RW, .accessfn = access_el1nvpct,
.nv2_redirect_offset = 0x180 | NV2_REDIR_NO_NV1,
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
.writefn = gt_phys_ctl_write, .raw_writefn = raw_write },
{ .name = "CNTV_CTL_EL02", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 1,
.type = ARM_CP_IO | ARM_CP_ALIAS,
- .access = PL2_RW, .accessfn = e2h_access,
+ .access = PL2_RW, .accessfn = access_el1nvvct,
.nv2_redirect_offset = 0x170 | NV2_REDIR_NO_NV1,
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
.writefn = gt_virt_ctl_write, .raw_writefn = raw_write },
@@ -8424,14 +8465,14 @@ static const ARMCPRegInfo vhe_reginfo[] = {
.type = ARM_CP_IO | ARM_CP_ALIAS,
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
.nv2_redirect_offset = 0x178 | NV2_REDIR_NO_NV1,
- .access = PL2_RW, .accessfn = e2h_access,
+ .access = PL2_RW, .accessfn = access_el1nvpct,
.writefn = gt_phys_cval_write, .raw_writefn = raw_write },
{ .name = "CNTV_CVAL_EL02", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 2,
.type = ARM_CP_IO | ARM_CP_ALIAS,
.nv2_redirect_offset = 0x168 | NV2_REDIR_NO_NV1,
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
- .access = PL2_RW, .accessfn = e2h_access,
+ .access = PL2_RW, .accessfn = access_el1nvvct,
.writefn = gt_virt_cval_write, .raw_writefn = raw_write },
#endif
};
--
2.34.1
- [PULL 00/14] target-arm queue, Peter Maydell, 2024/03/08
- [PULL 02/14] target/arm: Timer _EL02 registers UNDEF for E2H == 0, Peter Maydell, 2024/03/08
- [PULL 01/14] target/arm: Move some register related defines to internals.h, Peter Maydell, 2024/03/08
- [PULL 06/14] target/arm: Define CNTPCTSS_EL0 and CNTVCTSS_EL0, Peter Maydell, 2024/03/08
- [PULL 07/14] target/arm: Implement FEAT_ECV CNTPOFF_EL2 handling, Peter Maydell, 2024/03/08
- [PULL 05/14] target/arm: Implement new FEAT_ECV trap bits,
Peter Maydell <=
- [PULL 08/14] target/arm: Enable FEAT_ECV for 'max' CPU, Peter Maydell, 2024/03/08
- [PULL 04/14] target/arm: Don't allow RES0 CNTHCTL_EL2 bits to be written, Peter Maydell, 2024/03/08
- [PULL 11/14] tests/qtest: Add STM32L4x5 GPIO QTest testcase, Peter Maydell, 2024/03/08
- [PULL 13/14] hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later, Peter Maydell, 2024/03/08
- [PULL 12/14] target/arm: Fix 32-bit SMOPA, Peter Maydell, 2024/03/08
- [PULL 03/14] target/arm: use FIELD macro for CNTHCTL bit definitions, Peter Maydell, 2024/03/08
- [PULL 10/14] hw/arm: Connect STM32L4x5 GPIO to STM32L4x5 SoC, Peter Maydell, 2024/03/08
- [PULL 14/14] target/arm: Move v7m-related code from cpu32.c into a separate file, Peter Maydell, 2024/03/08
- [PULL 09/14] hw/gpio: Implement STM32L4x5 GPIO, Peter Maydell, 2024/03/08
- Re: [PULL 00/14] target-arm queue, Peter Maydell, 2024/03/09