[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/5] target/arm: MTE privileged system mode assembly
From: |
Rémi Denis-Courmont |
Subject: |
[PATCH 4/5] target/arm: MTE privileged system mode assembly |
Date: |
Fri, 13 Mar 2020 16:00:22 +0200 |
From: Rémi Denis-Courmont <address@hidden>
This adds all remaining MTE instructions for EL1, EL2 and EL3 on a
processor with ID_AA64PFR1_EL1.MTE == 1.
Signed-off-by: Rémi Denis-Courmont <address@hidden>
---
target/arm/cpu64.c | 8 +++---
target/arm/helper.c | 19 ++++++++++++++
target/arm/translate-a64.c | 52 +++++++++++++++++++++++++++++++++++---
3 files changed, 71 insertions(+), 8 deletions(-)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index a72dfd3d98..749eb93872 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -665,13 +665,11 @@ static void aarch64_max_initfn(Object *obj)
t = cpu->isar.id_aa64pfr1;
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
-#ifdef CONFIG_USER_ONLY
- /* All MTE instructions and processor states are supported for user
- * mode. This corresponds to feature field value 1 (field value 2
- * implies MemTag memory support).
+ /* All MTE instructions and processor states are supported. This
+ * corresponds to feature field value 1 (field value 2 implies MemTag
+ * memory support).
*/
t = FIELD_DP64(t, ID_AA64PFR1, MTE, 1);
-#endif
cpu->isar.id_aa64pfr1 = t;
t = cpu->isar.id_aa64mmfr1;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index dd64fcb4ef..630dc04302 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6906,10 +6906,29 @@ static const ARMCPRegInfo mte_reginfo[] = {
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 5,
.access = PL0_W, .type = ARM_CP_NOP,
.accessfn = aa64_cacheop_poc_access },
+ { .name = "RGSR_EL1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 5,
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, rgsr_el1) },
+ { .name = "GCR_EL1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 6,
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, gcr_el1) },
{ .name = "TCO", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
.access = PL0_RW, .type = ARM_CP_NO_RAW,
.readfn = tco_read, .writefn = tco_write },
+ { .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 0, .crn = 6, .crm = 5, .opc2 = 0,
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, tfsr_el[1]) },
+ { .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 5, .opc2 = 0,
+ .access = PL2_RW, .type = ARM_CP_ALIAS,
+ .fieldoffset = offsetof(CPUARMState, tfsr_el[1]) },
+ { .name = "TFSR_EL3", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 5, .opc2 = 0,
+ .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, tfsr_el[3]) },
+ { .name = "TFSRE0_EL1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 0, .crn = 6, .crm = 6, .opc2 = 1,
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, tfsre0_el1) },
REGINFO_SENTINEL
};
#endif
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 6d86480043..9382f53794 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -2716,6 +2716,38 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(clean_addr);
}
+#ifndef CONFIG_USER_ONLY
+static void disas_ldst_memtag_vec(DisasContext *s, int rn, int rt,
+ bool is_load)
+{
+ TCGv_i64 tcg_addr;
+
+ if (rn == rt) {
+ return;
+ }
+
+ if (rn == 31) {
+ gen_check_sp_alignment(s);
+ }
+
+ /* The starting point between the specified address and the aligned
+ * address is implementation defined. We start at the aligned address.
+ */
+ tcg_addr = tcg_temp_new_i64();
+ tcg_gen_andi_i64(tcg_addr, cpu_reg_sp(s, rn),
+ ~((16 * ARM_TAG_GRANULE) - 1));
+
+ /* In principles, memory access permissions should be checked here. */
+ if (is_load) {
+ tcg_gen_movi_i64(cpu_reg(s, rt), 0);
+ }
+
+ tcg_gen_addi_i64(cpu_reg_sp(s, rn), tcg_addr, 16 * ARM_TAG_GRANULE);
+
+ tcg_temp_free_i64(tcg_addr);
+}
+#endif
+
/* LDG, LDGV(EL1), ST(Z)(2)G, STGV */
static void disas_ldst_memtag(DisasContext *s, uint32_t insn)
{
@@ -2736,9 +2768,23 @@ static void disas_ldst_memtag(DisasContext *s, uint32_t
insn)
return;
}
- if (op2 == 0 && opc != 1) {
- unallocated_encoding(s);
- return;
+ if (op2 == 0) {
+ switch (opc) {
+ case 1:
+ break;
+#ifndef CONFIG_USER_ONLY
+ case 2:
+ case 3:
+ if (s->current_el > 0 && offset == 0) {
+ disas_ldst_memtag_vec(s, rn, rt, opc & 1);
+ return;
+ }
+#endif
+ /* fall through */
+ default:
+ unallocated_encoding(s);
+ return;
+ }
}
if (rn == 31) {
--
2.25.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH 4/5] target/arm: MTE privileged system mode assembly,
Rémi Denis-Courmont <=