diff mbox series

[6/7] target/arm: Define cortex-a76

Message ID 20220410055725.380246-7-richard.henderson@linaro.org
State New
Headers show
Series target/arm: More trivial features, A76, N1 | expand

Commit Message

Richard Henderson April 10, 2022, 5:57 a.m. UTC
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(+)

Comments

Peter Maydell April 11, 2022, 6:09 p.m. UTC | #1
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
Richard Henderson April 11, 2022, 6:30 p.m. UTC | #2
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~
Richard Henderson April 11, 2022, 11:56 p.m. UTC | #3
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 mbox series

Patch

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)