Skip to content

Commit

Permalink
target/arm: Add SMCR_ELx
Browse files Browse the repository at this point in the history
These cpregs control the streaming vector length and whether the
full a64 instruction set is allowed while in streaming mode.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220620175235.60881-7-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
rth7680 authored and pm215 committed Jun 27, 2022
1 parent c37e6ac commit de56198
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
8 changes: 6 additions & 2 deletions target/arm/cpu.h
Expand Up @@ -669,8 +669,8 @@ typedef struct CPUArchState {
float_status standard_fp_status;
float_status standard_fp_status_f16;

/* ZCR_EL[1-3] */
uint64_t zcr_el[4];
uint64_t zcr_el[4]; /* ZCR_EL[1-3] */
uint64_t smcr_el[4]; /* SMCR_EL[1-3] */
} vfp;
uint64_t exclusive_addr;
uint64_t exclusive_val;
Expand Down Expand Up @@ -1434,6 +1434,10 @@ FIELD(CPTR_EL3, TCPAC, 31, 1)
FIELD(SVCR, SM, 0, 1)
FIELD(SVCR, ZA, 1, 1)

/* Fields for SMCR_ELx. */
FIELD(SMCR, LEN, 0, 4)
FIELD(SMCR, FA64, 31, 1)

/* Write a new value to v7m.exception, thus transitioning into or out
* of Handler mode; this may result in a change of active stack pointer.
*/
Expand Down
41 changes: 41 additions & 0 deletions target/arm/helper.c
Expand Up @@ -5879,6 +5879,8 @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
*/
{ K(3, 0, 1, 2, 0), K(3, 4, 1, 2, 0), K(3, 5, 1, 2, 0),
"ZCR_EL1", "ZCR_EL2", "ZCR_EL12", isar_feature_aa64_sve },
{ K(3, 0, 1, 2, 6), K(3, 4, 1, 2, 6), K(3, 5, 1, 2, 6),
"SMCR_EL1", "SMCR_EL2", "SMCR_EL12", isar_feature_aa64_sme },

{ K(3, 0, 5, 6, 0), K(3, 4, 5, 6, 0), K(3, 5, 5, 6, 0),
"TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte },
Expand Down Expand Up @@ -6357,6 +6359,30 @@ static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
env->svcr = value;
}

static void smcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
int cur_el = arm_current_el(env);
int old_len = sve_vqm1_for_el(env, cur_el);
int new_len;

QEMU_BUILD_BUG_ON(ARM_MAX_VQ > R_SMCR_LEN_MASK + 1);
value &= R_SMCR_LEN_MASK | R_SMCR_FA64_MASK;
raw_write(env, ri, value);

/*
* Note that it is CONSTRAINED UNPREDICTABLE what happens to ZA storage
* when SVL is widened (old values kept, or zeros). Choose to keep the
* current values for simplicity. But for QEMU internals, we must still
* apply the narrower SVL to the Zregs and Pregs -- see the comment
* above aarch64_sve_narrow_vq.
*/
new_len = sve_vqm1_for_el(env, cur_el);
if (new_len < old_len) {
aarch64_sve_narrow_vq(env, new_len + 1);
}
}

static const ARMCPRegInfo sme_reginfo[] = {
{ .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
Expand All @@ -6367,6 +6393,21 @@ static const ARMCPRegInfo sme_reginfo[] = {
.access = PL0_RW, .type = ARM_CP_SME,
.fieldoffset = offsetof(CPUARMState, svcr),
.writefn = svcr_write, .raw_writefn = raw_write },
{ .name = "SMCR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 6,
.access = PL1_RW, .type = ARM_CP_SME,
.fieldoffset = offsetof(CPUARMState, vfp.smcr_el[1]),
.writefn = smcr_write, .raw_writefn = raw_write },
{ .name = "SMCR_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 6,
.access = PL2_RW, .type = ARM_CP_SME,
.fieldoffset = offsetof(CPUARMState, vfp.smcr_el[2]),
.writefn = smcr_write, .raw_writefn = raw_write },
{ .name = "SMCR_EL3", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 6,
.access = PL3_RW, .type = ARM_CP_SME,
.fieldoffset = offsetof(CPUARMState, vfp.smcr_el[3]),
.writefn = smcr_write, .raw_writefn = raw_write },
};
#endif /* TARGET_AARCH64 */

Expand Down

0 comments on commit de56198

Please sign in to comment.