qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/5] target/arm: MTE processor state


From: Rémi Denis-Courmont
Subject: [PATCH 1/5] target/arm: MTE processor state
Date: Fri, 13 Mar 2020 16:00:19 +0200

From: Rémi Denis-Courmont <address@hidden>

This adds architectural definitions and internal processor state for
the ARMv8.5-MemTag, a.k.a. MTE extension:
 - a new ISAR register feature field,
 - new ATA flag bits for tag access in SCR, HCR and SCTLR registers,
 - a TCO flag in PSTATE and SPSR_ELx registers,
 - new CPU registers for pseudo-random tags generation.

Signed-off-by: Rémi Denis-Courmont <address@hidden>
---
 target/arm/cpu.h        | 17 +++++++++++++++++
 target/arm/helper-a64.c |  2 ++
 target/arm/helper.c     | 17 +++++++++++++++++
 3 files changed, 36 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 4ffd991b6f..e19ce0d746 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -267,6 +267,14 @@ typedef struct CPUARMState {
     uint64_t elr_el[4]; /* AArch64 exception link regs  */
     uint64_t sp_el[4]; /* AArch64 banked stack pointers */
 
+    /* Tag registers */
+    uint64_t gcr_el1;
+    uint64_t rgsr_el1;
+    union {
+        uint64_t tfsre0_el1;
+        uint64_t tfsr_el[4];
+    };
+
     /* System control coprocessor (cp15) */
     struct {
         uint32_t c0_cpuid;
@@ -1259,6 +1267,7 @@ void pmu_init(ARMCPU *cpu);
 #define PSTATE_SS (1U << 21)
 #define PSTATE_PAN (1U << 22)
 #define PSTATE_UAO (1U << 23)
+#define PSTATE_TCO (1U << 25)
 #define PSTATE_V (1U << 28)
 #define PSTATE_C (1U << 29)
 #define PSTATE_Z (1U << 30)
@@ -2949,6 +2958,9 @@ typedef enum ARMASIdx {
     ARMASIdx_S = 1,
 } ARMASIdx;
 
+#define ARM_LOG2_TAG_GRANULE 4
+#define ARM_TAG_GRANULE (UINT64_C(1) << ARM_LOG2_TAG_GRANULE)
+
 /* Return the Exception Level targeted by debug exceptions. */
 static inline int arm_debug_target_el(CPUARMState *env)
 {
@@ -3777,6 +3789,11 @@ static inline bool isar_feature_aa64_bti(const 
ARMISARegisters *id)
     return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
 }
 
+static inline unsigned isar_feature_aa64_mte(const ARMISARegisters *id)
+{
+    return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE);
+}
+
 static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
 {
     return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index bc0649a44a..5c8d081d4c 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -1036,6 +1036,8 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t 
new_pc)
 
         env->aarch64 = 1;
         spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar);
+        /* TCO bit is copied from CPSR, not SPSR */
+        spsr = (spsr & ~PSTATE_TCO) | (env->pstate & PSTATE_TCO);
         pstate_write(env, spsr);
         if (!arm_singlestep_active(env)) {
             env->pstate &= ~PSTATE_SS;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b61ee73d18..38500e4f92 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1993,6 +1993,9 @@ static void scr_write(CPUARMState *env, const 
ARMCPRegInfo *ri, uint64_t value)
     if (cpu_isar_feature(aa64_pauth, cpu)) {
         valid_mask |= SCR_API | SCR_APK;
     }
+    if (cpu_isar_feature(aa64_mte, cpu) >= 2) {
+        valid_mask |= SCR_ATA;
+    }
 
     /* Clear all-context RES0 bits.  */
     value &= valid_mask;
@@ -4691,6 +4694,11 @@ static void sctlr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
         value &= ~SCTLR_M;
     }
 
+    if (cpu_isar_feature(aa64_mte, cpu) < 2) {
+        /* ATA and ATA0 are RES0 without full MTE implementation */
+        value &= ~(SCTLR_ATA | SCTLR_ATA0);
+    }
+
     raw_write(env, ri, value);
     /* ??? Lots of these bits are not implemented.  */
     /* This may enable/disable the MMU, so do a TLB flush.  */
@@ -5226,6 +5234,15 @@ static void do_hcr_write(CPUARMState *env, uint64_t 
value, uint64_t valid_mask)
         if (cpu_isar_feature(aa64_pauth, cpu)) {
             valid_mask |= HCR_API | HCR_APK;
         }
+        switch (cpu_isar_feature(aa64_mte, cpu)) {
+        default:
+            valid_mask |= HCR_ATA;
+            /* fall through */
+        case 1:
+            valid_mask |= HCR_DCT;
+        case 0:
+            break;
+        }
     }
 
     /* Clear RES0 bits.  */
-- 
2.25.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]