qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 12/16] target/arm: Add ZCR_ELx


From: Alex Bennée
Subject: Re: [Qemu-devel] [PATCH v2 12/16] target/arm: Add ZCR_ELx
Date: Mon, 22 Jan 2018 15:00:20 +0000
User-agent: mu4e 1.0-alpha3; emacs 26.0.91

Richard Henderson <address@hidden> writes:

> Define ZCR_EL[1-3].
>
> Signed-off-by: Richard Henderson <address@hidden>
> ---
>  target/arm/cpu.h    |  5 ++++
>  target/arm/helper.c | 80 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 85 insertions(+)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 0a923e42d8..c8e8155b6e 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -547,6 +547,9 @@ typedef struct CPUARMState {
>           */
>          float_status fp_status;
>          float_status standard_fp_status;
> +
> +        /* ZCR_EL[1-3] */
> +        uint64_t zcr_el[4];
>      } vfp;
>      uint64_t exclusive_addr;
>      uint64_t exclusive_val;
> @@ -921,6 +924,8 @@ void pmccntr_sync(CPUARMState *env);
>  #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 */
>
>  #define MDCR_EPMAD    (1U << 21)
>  #define MDCR_EDAD     (1U << 20)
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 6705903301..984a4b1306 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -4266,6 +4266,82 @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> +/* Return the exception level to which SVE-disabled exceptions should
> + * be taken, or 0 if SVE is enabled.
> + */
> +static int sve_exception_el(CPUARMState *env)
> +{
> +#ifndef CONFIG_USER_ONLY
> +    int highest_el = arm_highest_el(env);
> +    int current_el = arm_current_el(env);
> +    int i;
> +
> +    for (i = highest_el; i >= MAX(1, current_el); --i) {
> +        switch (i) {
> +        case 3:
> +            if ((env->cp15.cptr_el[3] & CPTR_EZ) == 0) {
> +                return 3;
> +            }
> +            break;
> +        case 2:
> +            if (env->cp15.cptr_el[2] & CPTR_TZ) {
> +                return 2;
> +            }
> +            break;
> +        case 1:

Might be worth a comment /* ZEN bits */

> +            switch (extract32(env->cp15.cpacr_el1, 16, 2)) {
> +            case 1:
> +                return current_el == 0 ? 1 : 0;
> +            case 3:
> +                return 0;
> +            default:
> +                return 1;

Am I missing something here?

"Traps SVE instructions and instructions that access SVE System registers at 
EL0 and EL1 to EL1,
or to EL2 when SCR_EL3.NS and HCR_EL2.TGE are both 1. Defined values
are:"


> +            }
> +        }
> +    }
> +#endif
> +    return 0;
> +}
> +
> +static CPAccessResult zcr_access(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                 bool isread)
> +{
> +    switch (sve_exception_el(env)) {
> +    case 3:
> +        return CP_ACCESS_TRAP_EL3;
> +    case 2:
> +        return CP_ACCESS_TRAP_EL2;
> +    case 1:
> +        return CP_ACCESS_TRAP;
> +    }
> +    return CP_ACCESS_OK;
> +}
> +
> +static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                      uint64_t value)
> +{
> +    /* Bits other than [3:0] are RAZ/WI.  */
> +    raw_write(env, ri, value & 0xf);
> +}
> +
> +static const ARMCPRegInfo sve_cp_reginfo[] = {
> +    { .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
> +      .access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
> +      .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
> +      .writefn = zcr_write, .raw_writefn = raw_write, },
> +    { .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 2, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
> +      .access = PL2_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
> +      .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
> +      .writefn = zcr_write, .raw_writefn = raw_write, },
> +    { .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 2, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
> +      .access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
> +      .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
> +      .writefn = zcr_write, .raw_writefn = raw_write, },
> +};
> +
>  void hw_watchpoint_update(ARMCPU *cpu, int n)
>  {
>      CPUARMState *env = &cpu->env;
> @@ -5332,6 +5408,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>          }
>          define_one_arm_cp_reg(cpu, &sctlr);
>      }
> +
> +    if (arm_feature(env, ARM_FEATURE_SVE)) {
> +        define_arm_cp_regs(cpu, sve_cp_reginfo);
> +    }
>  }
>
>  void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)


--
Alex Bennée



reply via email to

[Prev in Thread] Current Thread [Next in Thread]