mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
target/arm: Use FIELD definitions for CPACR, CPTR_ELx
We had a few CPTR_* bits defined, but missed quite a few. Complete all of the fields up to ARMv9.2. Use FIELD_EX64 instead of manual extract32. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220517054850.177016-3-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
5814d587fe
commit
fab8ad39fb
|
@ -761,7 +761,7 @@ static void do_cpu_reset(void *opaque)
|
|||
env->cp15.scr_el3 |= SCR_ATA;
|
||||
}
|
||||
if (cpu_isar_feature(aa64_sve, cpu)) {
|
||||
env->cp15.cptr_el[3] |= CPTR_EZ;
|
||||
env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
|
||||
}
|
||||
/* AArch64 kernels never boot in secure mode */
|
||||
assert(!info->secure_boot);
|
||||
|
|
|
@ -201,9 +201,11 @@ static void arm_cpu_reset(DeviceState *dev)
|
|||
/* Trap on btype=3 for PACIxSP. */
|
||||
env->cp15.sctlr_el[1] |= SCTLR_BT0;
|
||||
/* and to the FP/Neon instructions */
|
||||
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
|
||||
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
|
||||
CPACR_EL1, FPEN, 3);
|
||||
/* and to the SVE instructions */
|
||||
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
|
||||
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
|
||||
CPACR_EL1, ZEN, 3);
|
||||
/* with reasonable vector length */
|
||||
if (cpu_isar_feature(aa64_sve, cpu)) {
|
||||
env->vfp.zcr_el[1] =
|
||||
|
@ -252,7 +254,10 @@ static void arm_cpu_reset(DeviceState *dev)
|
|||
} else {
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
/* Userspace expects access to cp10 and cp11 for FP/Neon */
|
||||
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 4, 0xf);
|
||||
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
|
||||
CPACR, CP10, 3);
|
||||
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
|
||||
CPACR, CP11, 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1261,11 +1261,45 @@ void pmu_init(ARMCPU *cpu);
|
|||
#define SCTLR_SPINTMASK (1ULL << 62) /* FEAT_NMI */
|
||||
#define SCTLR_TIDCP (1ULL << 63) /* FEAT_TIDCP1 */
|
||||
|
||||
#define CPTR_TCPAC (1U << 31)
|
||||
#define CPTR_TTA (1U << 20)
|
||||
#define CPTR_TFP (1U << 10)
|
||||
#define CPTR_TZ (1U << 8) /* CPTR_EL2 */
|
||||
#define CPTR_EZ (1U << 8) /* CPTR_EL3 */
|
||||
/* Bit definitions for CPACR (AArch32 only) */
|
||||
FIELD(CPACR, CP10, 20, 2)
|
||||
FIELD(CPACR, CP11, 22, 2)
|
||||
FIELD(CPACR, TRCDIS, 28, 1) /* matches CPACR_EL1.TTA */
|
||||
FIELD(CPACR, D32DIS, 30, 1) /* up to v7; RAZ in v8 */
|
||||
FIELD(CPACR, ASEDIS, 31, 1)
|
||||
|
||||
/* Bit definitions for CPACR_EL1 (AArch64 only) */
|
||||
FIELD(CPACR_EL1, ZEN, 16, 2)
|
||||
FIELD(CPACR_EL1, FPEN, 20, 2)
|
||||
FIELD(CPACR_EL1, SMEN, 24, 2)
|
||||
FIELD(CPACR_EL1, TTA, 28, 1) /* matches CPACR.TRCDIS */
|
||||
|
||||
/* Bit definitions for HCPTR (AArch32 only) */
|
||||
FIELD(HCPTR, TCP10, 10, 1)
|
||||
FIELD(HCPTR, TCP11, 11, 1)
|
||||
FIELD(HCPTR, TASE, 15, 1)
|
||||
FIELD(HCPTR, TTA, 20, 1)
|
||||
FIELD(HCPTR, TAM, 30, 1) /* matches CPTR_EL2.TAM */
|
||||
FIELD(HCPTR, TCPAC, 31, 1) /* matches CPTR_EL2.TCPAC */
|
||||
|
||||
/* Bit definitions for CPTR_EL2 (AArch64 only) */
|
||||
FIELD(CPTR_EL2, TZ, 8, 1) /* !E2H */
|
||||
FIELD(CPTR_EL2, TFP, 10, 1) /* !E2H, matches HCPTR.TCP10 */
|
||||
FIELD(CPTR_EL2, TSM, 12, 1) /* !E2H */
|
||||
FIELD(CPTR_EL2, ZEN, 16, 2) /* E2H */
|
||||
FIELD(CPTR_EL2, FPEN, 20, 2) /* E2H */
|
||||
FIELD(CPTR_EL2, SMEN, 24, 2) /* E2H */
|
||||
FIELD(CPTR_EL2, TTA, 28, 1)
|
||||
FIELD(CPTR_EL2, TAM, 30, 1) /* matches HCPTR.TAM */
|
||||
FIELD(CPTR_EL2, TCPAC, 31, 1) /* matches HCPTR.TCPAC */
|
||||
|
||||
/* Bit definitions for CPTR_EL3 (AArch64 only) */
|
||||
FIELD(CPTR_EL3, EZ, 8, 1)
|
||||
FIELD(CPTR_EL3, TFP, 10, 1)
|
||||
FIELD(CPTR_EL3, ESM, 12, 1)
|
||||
FIELD(CPTR_EL3, TTA, 20, 1)
|
||||
FIELD(CPTR_EL3, TAM, 30, 1)
|
||||
FIELD(CPTR_EL3, TCPAC, 31, 1)
|
||||
|
||||
#define MDCR_EPMAD (1U << 21)
|
||||
#define MDCR_EDAD (1U << 20)
|
||||
|
|
|
@ -766,11 +766,14 @@ 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 |= (1 << 31) | (1 << 30) | (0xf << 20);
|
||||
mask |= R_CPACR_ASEDIS_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 |= (1 << 31);
|
||||
value |= R_CPACR_ASEDIS_MASK;
|
||||
}
|
||||
|
||||
/* VFPv3 and upwards with NEON implement 32 double precision
|
||||
|
@ -778,7 +781,7 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
*/
|
||||
if (!cpu_isar_feature(aa32_simd_r32, env_archcpu(env))) {
|
||||
/* D32DIS [30] is RAO/WI if D16-31 are not implemented. */
|
||||
value |= (1 << 30);
|
||||
value |= R_CPACR_D32DIS_MASK;
|
||||
}
|
||||
}
|
||||
value &= mask;
|
||||
|
@ -790,8 +793,8 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
*/
|
||||
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
|
||||
!arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
|
||||
value &= ~(0xf << 20);
|
||||
value |= env->cp15.cpacr_el1 & (0xf << 20);
|
||||
mask = R_CPACR_CP11_MASK | R_CPACR_CP10_MASK;
|
||||
value = (value & ~mask) | (env->cp15.cpacr_el1 & mask);
|
||||
}
|
||||
|
||||
env->cp15.cpacr_el1 = value;
|
||||
|
@ -807,7 +810,7 @@ static uint64_t cpacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
|||
|
||||
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
|
||||
!arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
|
||||
value &= ~(0xf << 20);
|
||||
value = ~(R_CPACR_CP11_MASK | R_CPACR_CP10_MASK);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -827,11 +830,11 @@ static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
if (arm_feature(env, ARM_FEATURE_V8)) {
|
||||
/* Check if CPACR accesses are to be trapped to EL2 */
|
||||
if (arm_current_el(env) == 1 && arm_is_el2_enabled(env) &&
|
||||
(env->cp15.cptr_el[2] & CPTR_TCPAC)) {
|
||||
FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, TCPAC)) {
|
||||
return CP_ACCESS_TRAP_EL2;
|
||||
/* Check if CPACR accesses are to be trapped to EL3 */
|
||||
} else if (arm_current_el(env) < 3 &&
|
||||
(env->cp15.cptr_el[3] & CPTR_TCPAC)) {
|
||||
FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, TCPAC)) {
|
||||
return CP_ACCESS_TRAP_EL3;
|
||||
}
|
||||
}
|
||||
|
@ -843,7 +846,8 @@ static CPAccessResult cptr_access(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
bool isread)
|
||||
{
|
||||
/* Check if CPTR accesses are set to trap to EL3 */
|
||||
if (arm_current_el(env) == 2 && (env->cp15.cptr_el[3] & CPTR_TCPAC)) {
|
||||
if (arm_current_el(env) == 2 &&
|
||||
FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, TCPAC)) {
|
||||
return CP_ACCESS_TRAP_EL3;
|
||||
}
|
||||
|
||||
|
@ -5343,8 +5347,8 @@ static void cptr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
*/
|
||||
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
|
||||
!arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
|
||||
value &= ~(0x3 << 10);
|
||||
value |= env->cp15.cptr_el[2] & (0x3 << 10);
|
||||
uint64_t mask = R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
|
||||
value = (value & ~mask) | (env->cp15.cptr_el[2] & mask);
|
||||
}
|
||||
env->cp15.cptr_el[2] = value;
|
||||
}
|
||||
|
@ -5359,7 +5363,7 @@ static uint64_t cptr_el2_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
|||
|
||||
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
|
||||
!arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
|
||||
value |= 0x3 << 10;
|
||||
value |= R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -6147,8 +6151,7 @@ int sve_exception_el(CPUARMState *env, int el)
|
|||
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
|
||||
|
||||
if (el <= 1 && (hcr_el2 & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
|
||||
/* Check CPACR.ZEN. */
|
||||
switch (extract32(env->cp15.cpacr_el1, 16, 2)) {
|
||||
switch (FIELD_EX64(env->cp15.cpacr_el1, CPACR_EL1, ZEN)) {
|
||||
case 1:
|
||||
if (el != 0) {
|
||||
break;
|
||||
|
@ -6161,7 +6164,7 @@ int sve_exception_el(CPUARMState *env, int el)
|
|||
}
|
||||
|
||||
/* Check CPACR.FPEN. */
|
||||
switch (extract32(env->cp15.cpacr_el1, 20, 2)) {
|
||||
switch (FIELD_EX64(env->cp15.cpacr_el1, CPACR_EL1, FPEN)) {
|
||||
case 1:
|
||||
if (el != 0) {
|
||||
break;
|
||||
|
@ -6178,8 +6181,7 @@ int sve_exception_el(CPUARMState *env, int el)
|
|||
*/
|
||||
if (el <= 2) {
|
||||
if (hcr_el2 & HCR_E2H) {
|
||||
/* Check CPTR_EL2.ZEN. */
|
||||
switch (extract32(env->cp15.cptr_el[2], 16, 2)) {
|
||||
switch (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, ZEN)) {
|
||||
case 1:
|
||||
if (el != 0 || !(hcr_el2 & HCR_TGE)) {
|
||||
break;
|
||||
|
@ -6190,8 +6192,7 @@ int sve_exception_el(CPUARMState *env, int el)
|
|||
return 2;
|
||||
}
|
||||
|
||||
/* Check CPTR_EL2.FPEN. */
|
||||
switch (extract32(env->cp15.cptr_el[2], 20, 2)) {
|
||||
switch (FIELD_EX32(env->cp15.cptr_el[2], CPTR_EL2, FPEN)) {
|
||||
case 1:
|
||||
if (el == 2 || !(hcr_el2 & HCR_TGE)) {
|
||||
break;
|
||||
|
@ -6202,10 +6203,10 @@ int sve_exception_el(CPUARMState *env, int el)
|
|||
return 0;
|
||||
}
|
||||
} else if (arm_is_el2_enabled(env)) {
|
||||
if (env->cp15.cptr_el[2] & CPTR_TZ) {
|
||||
if (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, TZ)) {
|
||||
return 2;
|
||||
}
|
||||
if (env->cp15.cptr_el[2] & CPTR_TFP) {
|
||||
if (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, TFP)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -6213,7 +6214,7 @@ int sve_exception_el(CPUARMState *env, int el)
|
|||
|
||||
/* CPTR_EL3. Since EZ is negative we must check for EL3. */
|
||||
if (arm_feature(env, ARM_FEATURE_EL3)
|
||||
&& !(env->cp15.cptr_el[3] & CPTR_EZ)) {
|
||||
&& !FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, EZ)) {
|
||||
return 3;
|
||||
}
|
||||
#endif
|
||||
|
@ -13396,7 +13397,7 @@ int fp_exception_el(CPUARMState *env, int cur_el)
|
|||
* This register is ignored if E2H+TGE are both set.
|
||||
*/
|
||||
if ((hcr_el2 & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
|
||||
int fpen = extract32(env->cp15.cpacr_el1, 20, 2);
|
||||
int fpen = FIELD_EX64(env->cp15.cpacr_el1, CPACR_EL1, FPEN);
|
||||
|
||||
switch (fpen) {
|
||||
case 0:
|
||||
|
@ -13442,8 +13443,7 @@ int fp_exception_el(CPUARMState *env, int cur_el)
|
|||
*/
|
||||
if (cur_el <= 2) {
|
||||
if (hcr_el2 & HCR_E2H) {
|
||||
/* Check CPTR_EL2.FPEN. */
|
||||
switch (extract32(env->cp15.cptr_el[2], 20, 2)) {
|
||||
switch (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, FPEN)) {
|
||||
case 1:
|
||||
if (cur_el != 0 || !(hcr_el2 & HCR_TGE)) {
|
||||
break;
|
||||
|
@ -13454,14 +13454,14 @@ int fp_exception_el(CPUARMState *env, int cur_el)
|
|||
return 2;
|
||||
}
|
||||
} else if (arm_is_el2_enabled(env)) {
|
||||
if (env->cp15.cptr_el[2] & CPTR_TFP) {
|
||||
if (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, TFP)) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* CPTR_EL3 : present in v8 */
|
||||
if (env->cp15.cptr_el[3] & CPTR_TFP) {
|
||||
if (FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, TFP)) {
|
||||
/* Trap all FP ops to EL3 */
|
||||
return 3;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue