From: Richard Henderson Date: Wed, 8 Oct 2025 21:55:46 +0000 (-0700) Subject: target/arm: Implement GCSSTR, GCSSTTR X-Git-Tag: v10.2.0-rc1~67^2~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6a5596bad37e62800e9d8ed8d35cb6a1af1030ba;p=thirdparty%2Fqemu.git target/arm: Implement GCSSTR, GCSSTTR Note that CreateAccDescGCS() does not enable tagchecked, and Data Aborts from GCS instructions do not set iss.isv. Reviewed-by: Pierrick Bouvier Signed-off-by: Richard Henderson Message-id: 20251008215613.300150-47-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode index 8283a9c83d..2ae73f443a 100644 --- a/target/arm/tcg/a64.decode +++ b/target/arm/tcg/a64.decode @@ -571,6 +571,9 @@ LDAPR_i 10 011001 10 0 ......... 00 ..... ..... @ldapr_stlr_i sign=1 ext LDAPR_i 00 011001 11 0 ......... 00 ..... ..... @ldapr_stlr_i sign=1 ext=1 sz=0 LDAPR_i 01 011001 11 0 ......... 00 ..... ..... @ldapr_stlr_i sign=1 ext=1 sz=1 +# GCSSTR, GCSSTTR +GCSSTR 11011001 000 11111 000 unpriv:1 11 rn:5 rt:5 + # Load/store multiple structures # The 4-bit opcode in [15:12] encodes repeat count and structure elements &ldst_mult rm rn rt sz q p rpt selem diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index c037119cdf..b72aa968cd 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -139,6 +139,12 @@ static int core_a64_user_mem_index(DisasContext *s, bool unpriv) return arm_to_core_mmu_idx(full_a64_user_mem_index(s, unpriv)); } +/* For a given translation regime, return the core mmu_idx for gcs access. */ +static int core_gcs_mem_index(ARMMMUIdx armidx) +{ + return arm_to_core_mmu_idx(regime_to_gcs(armidx)); +} + static void set_btype_raw(int val) { tcg_gen_st_i32(tcg_constant_i32(val), tcg_env, @@ -3989,6 +3995,42 @@ static bool trans_STLR_i(DisasContext *s, arg_ldapr_stlr_i *a) return true; } +static bool trans_GCSSTR(DisasContext *s, arg_GCSSTR *a) +{ + ARMMMUIdx armidx; + + if (!dc_isar_feature(aa64_gcs, s)) { + return false; + } + + /* + * The pseudocode for GCSSTTR is + * + * effective_el = AArch64.IsUnprivAccessPriv() ? PSTATE.EL : EL0; + * if (effective_el == PSTATE.EL) CheckGCSSTREnabled(); + * + * We have cached the result of IsUnprivAccessPriv in DisasContext, + * but since we need the result of full_a64_user_mem_index anyway, + * use the mmu_idx test as a proxy for the effective_el test. + */ + armidx = full_a64_user_mem_index(s, a->unpriv); + if (armidx == s->mmu_idx && s->gcsstr_el != 0) { + gen_exception_insn_el(s, 0, EXCP_UDEF, + syn_gcs_gcsstr(a->rn, a->rt), + s->gcsstr_el); + return true; + } + + if (a->rn == 31) { + gen_check_sp_alignment(s); + } + tcg_gen_qemu_st_i64(cpu_reg(s, a->rt), + clean_data_tbi(s, cpu_reg_sp(s, a->rn)), + core_gcs_mem_index(armidx), + finalize_memop(s, MO_64 | MO_ALIGN)); + return true; +} + static bool trans_LD_mult(DisasContext *s, arg_ldst_mult *a) { TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;