Message ID | 20220410055725.380246-7-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | target/arm: More trivial features, A76, N1 | expand |
On Sun, 10 Apr 2022 at 07:13, Richard Henderson <richard.henderson@linaro.org> wrote: > > Enable the a76 for virt and sbsa board use. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > hw/arm/sbsa-ref.c | 1 + > hw/arm/virt.c | 1 + > target/arm/cpu64.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 66 insertions(+) > > diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c > index 2387401963..2ddde88f5e 100644 > --- a/hw/arm/sbsa-ref.c > +++ b/hw/arm/sbsa-ref.c > @@ -145,6 +145,7 @@ static const int sbsa_ref_irqmap[] = { > static const char * const valid_cpus[] = { > ARM_CPU_TYPE_NAME("cortex-a57"), > ARM_CPU_TYPE_NAME("cortex-a72"), > + ARM_CPU_TYPE_NAME("cortex-a76"), > ARM_CPU_TYPE_NAME("max"), > }; > > diff --git a/hw/arm/virt.c b/hw/arm/virt.c > index d2e5ecd234..ce15c36a7f 100644 > --- a/hw/arm/virt.c > +++ b/hw/arm/virt.c > @@ -202,6 +202,7 @@ static const char *valid_cpus[] = { > ARM_CPU_TYPE_NAME("cortex-a53"), > ARM_CPU_TYPE_NAME("cortex-a57"), > ARM_CPU_TYPE_NAME("cortex-a72"), > + ARM_CPU_TYPE_NAME("cortex-a76"), > ARM_CPU_TYPE_NAME("a64fx"), > ARM_CPU_TYPE_NAME("host"), > ARM_CPU_TYPE_NAME("max"), Need to update the list in docs/system/arm/virt.rst as well. > diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c > index 199ca437a0..a00c02be2c 100644 > --- a/target/arm/cpu64.c > +++ b/target/arm/cpu64.c > @@ -251,6 +251,69 @@ static void aarch64_a72_initfn(Object *obj) > define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); > } > > +static void aarch64_a76_initfn(Object *obj) > +{ > + ARMCPU *cpu = ARM_CPU(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_GENERIC_TIMER); > + set_feature(&cpu->env, ARM_FEATURE_AARCH64); > + set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); > + set_feature(&cpu->env, ARM_FEATURE_EL2); > + set_feature(&cpu->env, ARM_FEATURE_EL3); > + set_feature(&cpu->env, ARM_FEATURE_PMU); > + > + /* Ordered by B2.4 AArch64 registers by functional group */ > + cpu->clidr = 0x82000023; > + cpu->ctr = 0x8444C004; > + cpu->dcz_blocksize = 4; > + cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; > + cpu->isar.id_aa64isar0 = 0x0000100010211120ull; > + cpu->isar.id_aa64isar1 = 0x0000000000100001ull; > + cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; > + cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; > + cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; > + cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; This has the GIC field clear. On the one hand this is true also of all our other CPU implementations. On the other hand if we wire up a GICv3 in the board code then we will be presenting the GIC CPU interface registers, which is what this ID register field is supposed to be telling software. I guess we should handle this by having gicv3_init_cpuif() arrange for the ID field to be set. Which is mildly painful, because that will mean the value for the cpreg isn't constant. (In real hardware the cpuif really is part of the CPU proper, so it (ie the sysregs for the GICv3) exists whether the GICv3 proper is present somewhere outside the CPU in the SoC. But our implementation doesn't put the dividing line quite where the h/w does.) > + cpu->isar.id_aa64pfr1 = 0x0000000000000010ull; > + cpu->isar.id_dfr0 = 0x04010088; > + cpu->isar.id_isar0 = 0x02101110; > + cpu->isar.id_isar1 = 0x13112111; > + cpu->isar.id_isar2 = 0x21232042; > + cpu->isar.id_isar3 = 0x01112131; > + cpu->isar.id_isar4 = 0x00010142; > + cpu->isar.id_isar5 = 0x01011121; > + cpu->isar.id_isar6 = 0x00000010; > + cpu->isar.id_mmfr0 = 0x10201105; > + cpu->isar.id_mmfr1 = 0x40000000; > + cpu->isar.id_mmfr2 = 0x01260000; > + cpu->isar.id_mmfr3 = 0x02122211; > + cpu->isar.id_mmfr4 = 0x00021110; > + cpu->isar.id_pfr0 = 0x10010131; > + cpu->isar.id_pfr1 = 0x10010000; Here you have set the GIC field. We should at least be consistent :-) > + cpu->isar.id_pfr2 = 0x00000011; > + cpu->midr = 0x413fd0b1; This is r3p1; the r4p1 TRM is available so we might as well claim to be that. > + > + /* From B2.18 CCSIDR_EL1 */ > + cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */ > + cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */ > + cpu->ccsidr[2] = 0x707fe03a; /* 512KB L2 cache */ > + > + /* From B2.93 SCTLR_EL3 */ > + cpu->reset_sctlr = 0x30c50838; > + > + /* From B4.23 ICH_VTR_EL2 */ > + cpu->gic_num_lrs = 4; > + cpu->gic_vpribits = 5; > + cpu->gic_vprebits = 5; (side note, we should really support having the non-virtual pribits/prebits for the GIC be configurable too. I have a half-written set of patches for that.) > + > + /* From B5.1 AdvSIMD AArch64 register summary */ > + cpu->isar.mvfr0 = 0x10110222; > + cpu->isar.mvfr1 = 0x13211111; > + cpu->isar.mvfr2 = 0x00000043; Missing (just cross-checking what other CPUs are setting): cpu->revidr cpu->reset_fpsid cpu->id_afr0 cpu->isar.dbgdidr > +} > + > void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) > { > /* > @@ -935,6 +998,7 @@ static const ARMCPUInfo aarch64_cpus[] = { > { .name = "cortex-a57", .initfn = aarch64_a57_initfn }, > { .name = "cortex-a53", .initfn = aarch64_a53_initfn }, > { .name = "cortex-a72", .initfn = aarch64_a72_initfn }, > + { .name = "cortex-a76", .initfn = aarch64_a76_initfn }, > { .name = "a64fx", .initfn = aarch64_a64fx_initfn }, > { .name = "max", .initfn = aarch64_max_initfn }, > #if defined(CONFIG_KVM) || defined(CONFIG_HVF) > -- thanks -- PMM
On 4/11/22 11:09, Peter Maydell wrote: >> + cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; > > This has the GIC field clear. On the one hand this is true > also of all our other CPU implementations. On the other hand > if we wire up a GICv3 in the board code then we will be > presenting the GIC CPU interface registers, which is what this > ID register field is supposed to be telling software. > I guess we should handle this by having gicv3_init_cpuif() > arrange for the ID field to be set. Which is mildly painful, > because that will mean the value for the cpreg isn't constant. We already handle this via id_aa64pfr0_read(). >> + cpu->isar.id_pfr1 = 0x10010000; > > Here you have set the GIC field. We should at least be consistent :-) Oops. :-) We have id_pfr1_read() for that as well. >> + cpu->midr = 0x413fd0b1; > > This is r3p1; the r4p1 TRM is available so we might as > well claim to be that. Ok. > Missing (just cross-checking what other CPUs are setting): > cpu->revidr > cpu->reset_fpsid > cpu->id_afr0 revidr and id_afr0 are 0 -- explicit zero required? We certainly assume we begin with zero for other registers for other cpus... FPSID is deprecated, and not mentioned in the a76 or n1 specs. Presumably this is because it is not accessible at all: FPSID is not accessible from EL0 for VFPv3, and the A76 does not support aa32 at other than EL0. > cpu->isar.dbgdidr "If EL1 cannot use AArch32 then the implementation of this register is OPTIONAL and deprecated." r~
On 4/11/22 11:30, Richard Henderson wrote: >> cpu->isar.dbgdidr > > "If EL1 cannot use AArch32 then the implementation of this register is OPTIONAL and > deprecated." Which we already handle in define_debug_regs by not defining DBGDIDR if this value is 0. r~
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 2387401963..2ddde88f5e 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -145,6 +145,7 @@ static const int sbsa_ref_irqmap[] = { static const char * const valid_cpus[] = { ARM_CPU_TYPE_NAME("cortex-a57"), ARM_CPU_TYPE_NAME("cortex-a72"), + ARM_CPU_TYPE_NAME("cortex-a76"), ARM_CPU_TYPE_NAME("max"), }; diff --git a/hw/arm/virt.c b/hw/arm/virt.c index d2e5ecd234..ce15c36a7f 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -202,6 +202,7 @@ static const char *valid_cpus[] = { ARM_CPU_TYPE_NAME("cortex-a53"), ARM_CPU_TYPE_NAME("cortex-a57"), ARM_CPU_TYPE_NAME("cortex-a72"), + ARM_CPU_TYPE_NAME("cortex-a76"), ARM_CPU_TYPE_NAME("a64fx"), ARM_CPU_TYPE_NAME("host"), ARM_CPU_TYPE_NAME("max"), diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 199ca437a0..a00c02be2c 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -251,6 +251,69 @@ static void aarch64_a72_initfn(Object *obj) define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); } +static void aarch64_a76_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(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_GENERIC_TIMER); + set_feature(&cpu->env, ARM_FEATURE_AARCH64); + set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); + set_feature(&cpu->env, ARM_FEATURE_EL2); + set_feature(&cpu->env, ARM_FEATURE_EL3); + set_feature(&cpu->env, ARM_FEATURE_PMU); + + /* Ordered by B2.4 AArch64 registers by functional group */ + cpu->clidr = 0x82000023; + cpu->ctr = 0x8444C004; + cpu->dcz_blocksize = 4; + cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; + cpu->isar.id_aa64isar0 = 0x0000100010211120ull; + cpu->isar.id_aa64isar1 = 0x0000000000100001ull; + cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; + cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; + cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; + cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; + cpu->isar.id_aa64pfr1 = 0x0000000000000010ull; + cpu->isar.id_dfr0 = 0x04010088; + cpu->isar.id_isar0 = 0x02101110; + cpu->isar.id_isar1 = 0x13112111; + cpu->isar.id_isar2 = 0x21232042; + cpu->isar.id_isar3 = 0x01112131; + cpu->isar.id_isar4 = 0x00010142; + cpu->isar.id_isar5 = 0x01011121; + cpu->isar.id_isar6 = 0x00000010; + cpu->isar.id_mmfr0 = 0x10201105; + cpu->isar.id_mmfr1 = 0x40000000; + cpu->isar.id_mmfr2 = 0x01260000; + cpu->isar.id_mmfr3 = 0x02122211; + cpu->isar.id_mmfr4 = 0x00021110; + cpu->isar.id_pfr0 = 0x10010131; + cpu->isar.id_pfr1 = 0x10010000; + cpu->isar.id_pfr2 = 0x00000011; + cpu->midr = 0x413fd0b1; + + /* From B2.18 CCSIDR_EL1 */ + cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */ + cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */ + cpu->ccsidr[2] = 0x707fe03a; /* 512KB L2 cache */ + + /* From B2.93 SCTLR_EL3 */ + cpu->reset_sctlr = 0x30c50838; + + /* From B4.23 ICH_VTR_EL2 */ + cpu->gic_num_lrs = 4; + cpu->gic_vpribits = 5; + cpu->gic_vprebits = 5; + + /* From B5.1 AdvSIMD AArch64 register summary */ + cpu->isar.mvfr0 = 0x10110222; + cpu->isar.mvfr1 = 0x13211111; + cpu->isar.mvfr2 = 0x00000043; +} + void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { /* @@ -935,6 +998,7 @@ static const ARMCPUInfo aarch64_cpus[] = { { .name = "cortex-a57", .initfn = aarch64_a57_initfn }, { .name = "cortex-a53", .initfn = aarch64_a53_initfn }, { .name = "cortex-a72", .initfn = aarch64_a72_initfn }, + { .name = "cortex-a76", .initfn = aarch64_a76_initfn }, { .name = "a64fx", .initfn = aarch64_a64fx_initfn }, { .name = "max", .initfn = aarch64_max_initfn }, #if defined(CONFIG_KVM) || defined(CONFIG_HVF)
Enable the a76 for virt and sbsa board use. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- hw/arm/sbsa-ref.c | 1 + hw/arm/virt.c | 1 + target/arm/cpu64.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+)