[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-arm] [PATCH 03/17] target/arm: Add MTE system registers
From: |
Peter Maydell |
Subject: |
Re: [Qemu-arm] [PATCH 03/17] target/arm: Add MTE system registers |
Date: |
Tue, 5 Feb 2019 19:27:54 +0000 |
On Mon, 14 Jan 2019 at 01:11, Richard Henderson
<address@hidden> wrote:
>
> This is TFSRE0_EL1, TFSR_EL1, TFSR_EL2, TFSR_EL3,
> RGSR_EL1, GCR_EL1, and PSTATE.TCO.
>
> Signed-off-by: Richard Henderson <address@hidden>
> ---
> target/arm/cpu.h | 5 +++++
> target/arm/translate.h | 11 ++++++++++
> target/arm/helper.c | 45 ++++++++++++++++++++++++++++++++++++++
> target/arm/translate-a64.c | 11 ++++++++++
> 4 files changed, 72 insertions(+)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 22163c9c3f..c8b447e30a 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -482,6 +482,11 @@ typedef struct CPUARMState {
> uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
> uint64_t vpidr_el2; /* Virtualization Processor ID Register */
> uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
> +#ifdef TARGET_AARCH64
> + uint64_t tfsr_el[4]; /* tfsrel0_el1 is index 0. */
> + uint64_t gcr_el1;
> + uint64_t rgsr_el1;
> +#endif
Are we going to add more fields inside this #ifdef or is it only
saving 12 words?
> } cp15;
>
> struct {
> diff --git a/target/arm/translate.h b/target/arm/translate.h
> index 5a101e1c6d..a24757d3d7 100644
> --- a/target/arm/translate.h
> +++ b/target/arm/translate.h
> @@ -204,6 +204,17 @@ static inline TCGv_i32 get_ahp_flag(void)
> return ret;
> }
>
> +/* Set bits within PSTATE. */
> +static inline void set_pstate_bits(uint32_t bits)
> +{
> + TCGv_i32 p = tcg_temp_new_i32();
> +
> + tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
> + tcg_gen_ori_i32(p, p, bits);
> + tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
> + tcg_temp_free_i32(p);
Maybe assert() that all the bits in the input are in the
set that we actually store in env->pstate, to catch attempts
to set NZCV, nRW, etc this way ?
> +}
> +
> /* Clear bits within PSTATE. */
> static inline void clear_pstate_bits(uint32_t bits)
> {
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 5a59fc4315..df43deb0f8 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -5132,6 +5132,48 @@ static const ARMCPRegInfo pauth_reginfo[] = {
> .fieldoffset = offsetof(CPUARMState, apib_key.hi) },
> REGINFO_SENTINEL
> };
> +
> +static uint64_t tco_read(CPUARMState *env, const ARMCPRegInfo *ri)
> +{
> + return env->pstate & PSTATE_TCO;
> +}
> +
> +static void tco_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
> +{
> + env->pstate = (env->pstate & ~PSTATE_TCO) | (val & PSTATE_TCO);
> +}
> +
> +static const ARMCPRegInfo mte_reginfo[] = {
> + { .name = "TFSRE0_EL1", .state = ARM_CP_STATE_AA64,
> + .opc0 = 3, .opc1 = 0, .crn = 6, .crm = 6, .opc2 = 1,
> + .access = PL1_RW,
> + .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[0]) },
> + { .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64,
> + .opc0 = 3, .opc1 = 0, .crn = 6, .crm = 5, .opc2 = 0,
> + .access = PL1_RW,
> + .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
> + { .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
> + .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 5, .opc2 = 0,
> + .access = PL2_RW,
> + .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[2]) },
> + { .name = "TFSR_EL3", .state = ARM_CP_STATE_AA64,
> + .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 6, .opc2 = 0,
> + .access = PL3_RW,
> + .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[3]) },
> + { .name = "RGSR_EL1", .state = ARM_CP_STATE_AA64,
> + .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 5,
> + .access = PL1_RW,
> + .fieldoffset = offsetof(CPUARMState, cp15.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, cp15.gcr_el1) },
> + { .name = "TCO", .state = ARM_CP_STATE_AA64,
> + .opc0 = 0, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
Shouldn't this have opc0 = 3 ?
> + .type = ARM_CP_NO_RAW,
> + .access = PL0_RW, .readfn = tco_read, .writefn = tco_write },
> + REGINFO_SENTINEL
Missing GMID_EL1 ?
> +};
> #endif
>
> void register_cp_regs_for_features(ARMCPU *cpu)
> @@ -5923,6 +5965,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
> if (cpu_isar_feature(aa64_pauth, cpu)) {
> define_arm_cp_regs(cpu, pauth_reginfo);
> }
> + if (cpu_isar_feature(aa64_mte_insn_reg, cpu)) {
> + define_arm_cp_regs(cpu, mte_reginfo);
> + }
> #endif
> }
>
> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
> index 0286507bae..5c2577a9ac 100644
> --- a/target/arm/translate-a64.c
> +++ b/target/arm/translate-a64.c
> @@ -1668,6 +1668,17 @@ static void handle_msr_i(DisasContext *s, uint32_t
> insn,
> s->base.is_jmp = DISAS_UPDATE;
> break;
>
> + case 0x1c: /* TCO */
> + if (!dc_isar_feature(aa64_mte_insn_reg, s)) {
> + goto do_unallocated;
> + }
> + if (crm & 1) {
> + set_pstate_bits(PSTATE_TCO);
> + } else {
> + clear_pstate_bits(PSTATE_TCO);
> + }
> + break;
Don't we need to break the TB here or something to pick up
the new value of TCO when we generate code for a following
load or store ? (TCO is self-synchronizing so there is no
requirement for an ISB before it takes effect.)
thanks
-- PMM
- Re: [Qemu-arm] [PATCH 03/17] target/arm: Add MTE system registers,
Peter Maydell <=