[PATCH v2 4/8] target/arm: Add new feature ARM_FEATURE_NEON_TRAPS
Peter Maydell <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
The traps configurable via CPACR.ASEDIS and HCPTR.TASE that trap only Neon instructions are unfortunately IMPDEF about whether they are implemented or not, and there is no ID register field that identifies whether they are present. In practice, they are present on every implementation I have checked except for the Cortex-A8 (which was the first CPU with Neon). Add a new feature ARM_FEATURE_NEON_TRAPS which we set on every ARM_FEATURE_NEON CPU except the Cortex-A8, and make the CPACR.ASEDIS and HCPTR.TASE bits RAZ/WI unless the CPU has ARM_FEATURE_NEON and ARM_FEATURE_NEON_TRAPS. Signed-off-by: Peter Maydell <[email protected]> --- We seem to be a little confused about whether ARM_FEATURE_NEON means "AArch32 Neon" or "AArch32 Neon or AArch64 ASIMD". I have not attempted to unpick that here. I have also not gone so far as to set NEON_TRAPS for the accelerator CPUs, since they won't be using the sysreg access functions anyway and (other than KVM) they don't support AArch32. --- target/arm/cpu-max.c | 1 + target/arm/cpu.h | 7 +++++++ target/arm/cpu64.c | 1 + target/arm/helper.c | 17 +++++++++++++++-- target/arm/tcg/cpu32.c | 8 ++++++++ target/arm/tcg/cpu64.c | 10 ++++++++++ 6 files changed, 42 insertions(+), 2 deletions(-) diff --git a/target/arm/cpu-max.c b/target/arm/cpu-max.c index 88b7c04633..84fdd64c18 100644 --- a/target/arm/cpu-max.c +++ b/target/arm/cpu-max.c @@ -25,6 +25,7 @@ void aarch64_aa32_a57_init(Object *obj, bool aa32_only) cpu->dtb_compatible = "arm,cortex-a57"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); if (aarch64_enabled) { diff --git a/target/arm/cpu.h b/target/arm/cpu.h index c0492c8dfb..4f07332543 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2177,6 +2177,13 @@ enum arm_features { * CPU types added in future. */ ARM_FEATURE_BACKCOMPAT_CNTFRQ, /* 62.5MHz timer default */ + /* + * ARM_FEATURE_NEON_TRAPS should be set if the CPU implements the + * CPACR.ASEDIS and HCPTR.TASE bits for trapping A32 Neon. This + * is architecturally IMPDEF, but seems to be implemented by all + * ARM_FEATURE_NEON CPUs except the Cortex-A8. + */ + ARM_FEATURE_NEON_TRAPS, }; static inline int arm_feature(const CPUARMState *env, int feature) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 2816735577..65998d3c64 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -699,6 +699,7 @@ static void aarch64_a53_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a53"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_AARCH64); diff --git a/target/arm/helper.c b/target/arm/helper.c index 91b872dc77..6f33b1ef5e 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -573,14 +573,20 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, */ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) { /* VFP coprocessor: cp10 & cp11 [23:20] */ - mask |= R_CPACR_ASEDIS_MASK | - R_CPACR_D32DIS_MASK | + mask |= R_CPACR_D32DIS_MASK | R_CPACR_CP11_MASK | R_CPACR_CP10_MASK; if (!arm_feature(env, ARM_FEATURE_NEON)) { /* ASEDIS [31] bit is RAO/WI */ value |= R_CPACR_ASEDIS_MASK; + mask |= R_CPACR_ASEDIS_MASK; + } else if (arm_feature(env, ARM_FEATURE_NEON_TRAPS)) { + /* + * bit is present unless CPU doesn't implement ASEDIS + * (in which case it is RAZ/WI; this is the Cortex-A8) + */ + mask |= R_CPACR_ASEDIS_MASK; } /* @@ -4124,6 +4130,13 @@ uint64_t arm_hcrx_el2_eff(CPUARMState *env) static void cptr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { + if (!arm_feature(env, ARM_FEATURE_NEON_TRAPS)) { + /* + * If CPU doesn't implement HCPTR.TASE it's RAZ/WI. Note that + * NSACR.NSASEDIS being 1 overrides this. + */ + value &= ~R_HCPTR_TASE_MASK; + } /* * For A-profile AArch32 EL3, if NSACR.CP10 * is 0 then HCPTR.{TCP11,TCP10} ignore writes and read as 1. diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c index 8220d785f5..3df3ca38d6 100644 --- a/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c @@ -251,6 +251,10 @@ static void cortex_a8_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a8"; set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_NEON); + /* + * The Cortex-A8 doesn't have CPACR.ASEDIS and HCPTR.TASE, + * so don't set ARM_FEATURE_NEON_TRAPS. + */ set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); set_feature(&cpu->env, ARM_FEATURE_EL3); @@ -321,6 +325,7 @@ static void cortex_a9_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a9"; set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); set_feature(&cpu->env, ARM_FEATURE_EL3); set_feature(&cpu->env, ARM_FEATURE_PMU); @@ -389,6 +394,7 @@ static void cortex_a7_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a7"; set_feature(&cpu->env, ARM_FEATURE_V7VE); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); @@ -439,6 +445,7 @@ static void cortex_a15_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a15"; set_feature(&cpu->env, ARM_FEATURE_V7VE); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); @@ -634,6 +641,7 @@ static void cortex_r52_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_EL2); set_feature(&cpu->env, ARM_FEATURE_PMSA); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index 24f34947ec..820248cb9b 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -37,6 +37,7 @@ static void aarch64_a35_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a35"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_AARCH64); @@ -208,6 +209,7 @@ static void aarch64_a55_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a55"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_AARCH64); @@ -281,6 +283,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a72"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_AARCH64); @@ -341,6 +344,7 @@ static void aarch64_a76_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a76"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_AARCH64); @@ -415,6 +419,7 @@ static void aarch64_a78ae_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a78ae"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_AARCH64); set_feature(&cpu->env, ARM_FEATURE_EL2); @@ -488,6 +493,7 @@ static void aarch64_a64fx_initfn(Object *obj) cpu->dtb_compatible = "arm,a64fx"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_AARCH64); @@ -662,6 +668,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj) cpu->dtb_compatible = "arm,neoverse-n1"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_AARCH64); @@ -738,6 +745,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj) cpu->dtb_compatible = "arm,neoverse-v1"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_AARCH64); @@ -965,6 +973,7 @@ static void aarch64_a710_initfn(Object *obj) cpu->dtb_compatible = "arm,cortex-a710"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_AARCH64); @@ -1067,6 +1076,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj) cpu->dtb_compatible = "arm,neoverse-n2"; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); set_feature(&cpu->env, ARM_FEATURE_AARCH64); -- 2.43.0