On 7/8/25 13:17, Gustavo Romero wrote:
Add FEAT_SCTLR2, which introduces the SCTLR2_EL1, SCTLR2_EL2, and
SCTLR2_EL3 registers. These registers are extensions of the SCTLR_ELx
ones.

Because the bits in these registers depend on other CPU features, and
only FEAT_MEC is supported at the moment, this commit only implements
the EMEC bits in CTLR2_EL2 and SCTLR2_EL3.

Signed-off-by: Gustavo Romero <gustavo.rom...@linaro.org>
---
  docs/system/arm/emulation.rst |  1 +
  target/arm/cpu-features.h     |  5 +++
  target/arm/cpu.h              | 15 +++++++
  target/arm/helper.c           | 78 +++++++++++++++++++++++++++++++++++
  target/arm/internals.h        |  1 +
  target/arm/tcg/cpu64.c        |  1 +
  6 files changed, 101 insertions(+)

diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index 890dc6fee2..66043b0747 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -121,6 +121,7 @@ the following architecture extensions:
  - FEAT_RPRES (Increased precision of FRECPE and FRSQRTE)
  - FEAT_S2FWB (Stage 2 forced Write-Back)
  - FEAT_SB (Speculation Barrier)
+- FEAT_SCTLR2 (Extension to SCTLR_ELx)
  - FEAT_SEL2 (Secure EL2)
  - FEAT_SHA1 (SHA1 instructions)
  - FEAT_SHA256 (SHA256 instructions)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 552d8757b7..44d6b655a9 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -416,6 +416,11 @@ static inline bool isar_feature_aa64_rdm(const 
ARMISARegisters *id)
      return FIELD_EX64_IDREG(id, ID_AA64ISAR0, RDM) != 0;
  }
+static inline bool isar_feature_aa64_sctlr2(const ARMISARegisters *id)
+{
+    return FIELD_EX64_IDREG(id, ID_AA64MMFR3, SCTLRX) != 0;
+}
+
  static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id)
  {
      return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SHA3) != 0;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index a93eebe077..32d30b7bb9 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -337,6 +337,7 @@ typedef struct CPUArchState {
              };
              uint64_t sctlr_el[4];
          };
+        uint64_t sctlr2_el[4]; /* Extension to System control register. */
          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 */
@@ -1433,6 +1434,19 @@ void pmu_init(ARMCPU *cpu);
  #define SCTLR_SPINTMASK (1ULL << 62) /* FEAT_NMI */
  #define SCTLR_TIDCP   (1ULL << 63) /* FEAT_TIDCP1 */
+#define SCTLR2_EMEC (1ULL << 1) /* FEAT_MEC */
+#define SCTLR2_NMEA (1ULL << 2) /* FEAT_DoubleFault2 */
+#define SCTLR2_ENADERR (1ULL << 3) /* FEAT_ADERR */
+#define SCTLR2_ENANERR (1ULL << 4) /* FEAT_ANERR */
+#define SCTLR2_EASE (1ULL << 5) /* FEAT_DoubleFault2 */
+#define SCTLR2_ENIDCP128 (1ULL << 6) /* FEAT_SYSREG128 */
+#define SCTLR2_ENPACM (1ULL << 7) /* FEAT_PAuth_LR */
+#define SCTLR2_ENPACM0 (1ULL << 8 /* FEAT_PAuth_LR */
+#define SCTLR2_CPTA (1ULL << 9) /* FEAT_CPA2 */
+#define SCTLR2_CPTA0 (1ULL << 10) /* FEAT_CPA2 */
+#define SCTLR2_CPTM (1ULL << 11) /* FEAT_CPA2 */
+#define SCTLR2_CPTM0 (1ULL << 12) /* FEAT_CAP2 */
+
  #define CPSR_M (0x1fU)
  #define CPSR_T (1U << 5)
  #define CPSR_F (1U << 6)
@@ -1725,6 +1739,7 @@ static inline void xpsr_write(CPUARMState *env, uint32_t 
val, uint32_t mask)
  #define SCR_HXEN              (1ULL << 38)
  #define SCR_TRNDR             (1ULL << 40)
  #define SCR_ENTP2             (1ULL << 41)
+#define SCR_SCTLR2EN          (1ULL << 44)
  #define SCR_GPF               (1ULL << 48)
  #define SCR_MECEN             (1ULL << 49)
  #define SCR_NSE               (1ULL << 62)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 984406c945..5707eea822 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6144,6 +6144,8 @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU 
*cpu)
      static const struct E2HAlias aliases[] = {
          { K(3, 0,  1, 0, 0), K(3, 4,  1, 0, 0), K(3, 5, 1, 0, 0),
            "SCTLR", "SCTLR_EL2", "SCTLR_EL12" },
+        { K(3, 0,  1, 0, 3), K(3, 4,  1, 0, 3), K(3, 5, 1, 0, 3),
+          "SCTLR2_EL1", "SCTLR2_EL2", "SCTLR2_EL12" },
          { K(3, 0,  1, 0, 2), K(3, 4,  1, 1, 2), K(3, 5, 1, 0, 2),
            "CPACR", "CPTR_EL2", "CPACR_EL12" },
          { K(3, 0,  2, 0, 0), K(3, 4,  2, 0, 0), K(3, 5, 2, 0, 0),
@@ -7816,6 +7818,78 @@ static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
        .resetvalue = 0 },
  };
+static CPAccessResult sctlr2_el2_access(CPUARMState *env,
+                                        const ARMCPRegInfo *ri,
+                                        bool isread)
+{
+    if (arm_current_el(env) < 3 && !(env->cp15.scr_el3 & SCR_SCTLR2EN)) {
+        return CP_ACCESS_TRAP_EL3;
+    }

Missing a check for arm_feature(env, ARM_FEATURE_EL3).

+    return CP_ACCESS_OK;
+};

Stray ;

+
+static CPAccessResult sctlr2_el1_access(CPUARMState *env,
+                                        const ARMCPRegInfo *ri,
+                                        bool isread)
+{
+    CPAccessResult ret = access_tvm_trvm(env, ri, isread);
+    if (ret != CP_ACCESS_OK) {
+        return ret;
+    }
+    if (arm_current_el(env) < 2 && !(arm_hcrx_el2_eff(env) & HCRX_SCTLR2EN)) {
+        return CP_ACCESS_TRAP_EL2;
+    }
+    return sctlr2_el2_access(env, ri, isread);
+};

Stray ;

+
+static void sctlr2_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
+{
+    /* This register does not control any feature yet. */
+};

Stray ;

+
+static void sctlr2_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
+{
+    uint64_t valid_mask = 0;
+
+    if (cpu_isar_feature(aa64_mec, env_archcpu(env))) {
+        valid_mask |= SCTLR2_EMEC;
+    }
+    value &= valid_mask;
+    raw_write(env, ri, value);
+};

Stray ;

+
+static void sctlr2_el3_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
+{
+    uint64_t valid_mask = 0;
+
+    if (cpu_isar_feature(aa64_mec, env_archcpu(env))) {
+        valid_mask |= SCTLR2_EMEC;
+    }
+    value &= valid_mask;
+    raw_write(env, ri, value);
+};

Stray ;

Otherwise,
Reviewed-by: Richard Henderson <richard.hender...@linaro.org>


r~

Reply via email to