See inline.

On Wednesday, October 21, 2015, Pavel Fedin <p.fe...@samsung.com> wrote:

>  Hello!
>
> > -----Original Message-----
> > From: Shlomo Pongratz [mailto:shlomopongr...@gmail.com <javascript:;>]
> > Sent: Tuesday, October 20, 2015 8:22 PM
> > To: qemu-devel@nongnu.org <javascript:;>
> > Cc: p.fe...@samsung.com <javascript:;>; peter.mayd...@linaro.org
> <javascript:;>; eric.au...@linaro.org <javascript:;>;
> > shannon.z...@linaro.org <javascript:;>; imamm...@redhat.com
> <javascript:;>; ash...@broadcom.com <javascript:;>; Shlomo Pongratz
> > Subject: [PATCH RFC V5 9/9] hw/arm: Add virt-v3 machine that uses GIC-500
> >
> > From: Shlomo Pongratz <shlomo.pongr...@huawei.com <javascript:;>>
> >
> > Add virt-v3 machine that uses GIC-500.
>
>  We already concluded long time ago that adding virt-v3 machine is wrong
> approach. We already have gic-version property for the virt
> machine, and especially for you i left a TODO placeholder in
> gicv3_class_name() function. Just return name of your class there, and
> you're done.
>
>
I see, just how do I pass the gic version from the command line?


> > Registers the CPU system instructions and bind them to the GIC.
> > Pass the cores' affinity to the GIC.
> >
> > Signed-off-by: Shlomo Pongratz <shlomo.pongr...@huawei.com
> <javascript:;>>
> > ---
> >  hw/arm/virt.c         | 87
> ++++++++++++++++++++++++++++++++++++++++++++++-----
> >  include/hw/arm/fdt.h  |  2 ++
> >  include/hw/arm/virt.h |  1 +
> >  target-arm/machine.c  |  7 ++++-
> >  4 files changed, 88 insertions(+), 9 deletions(-)
> >
> > diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> > index 5d38c47..d4fb8f3 100644
> > --- a/hw/arm/virt.c
> > +++ b/hw/arm/virt.c
> > @@ -71,6 +71,7 @@ typedef struct VirtBoardInfo {
> >      uint32_t clock_phandle;
> >      uint32_t gic_phandle;
> >      uint32_t v2m_phandle;
> > +    const char *class_name;
> >  } VirtBoardInfo;
> >
> >  typedef struct {
> > @@ -86,6 +87,7 @@ typedef struct {
> >  } VirtMachineState;
> >
> >  #define TYPE_VIRT_MACHINE   MACHINE_TYPE_NAME("virt")
> > +#define TYPE_VIRTV3_MACHINE MACHINE_TYPE_NAME("virt-v3")
> >  #define VIRT_MACHINE(obj) \
> >      OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE)
> >  #define VIRT_MACHINE_GET_CLASS(obj) \
> > @@ -111,6 +113,7 @@ static const MemMapEntry a15memmap[] = {
> >      [VIRT_CPUPERIPHS] =         { 0x08000000, 0x00020000 },
> >      /* GIC distributor and CPU interfaces sit inside the CPU peripheral
> space */
> >      [VIRT_GIC_DIST] =           { 0x08000000, 0x00010000 },
> > +    /* Note on GICv3 VIRT_GIC_DIST_SPI takes place of VIRT_GIC_CPU */
>
>  Memory map of the "virt" machine already contains everything needed. BTW,
> what's "SPI"? "MBI", you meant? Well, we are going to
> have an ITS, so this simple message translator will not be needed.
>
Typo.

>
> >      [VIRT_GIC_CPU] =            { 0x08010000, 0x00010000 },
> >      [VIRT_GIC_V2M] =            { 0x08020000, 0x00001000 },
> >      /* The space in between here is reserved for GICv3 CPU/vCPU/HYP */
> > @@ -145,21 +148,26 @@ static VirtBoardInfo machines[] = {
> >          .cpu_model = "cortex-a15",
> >          .memmap = a15memmap,
> >          .irqmap = a15irqmap,
> > +        .class_name = TYPE_ARM_CPU,
> > +
> >      },
> >      {
> >          .cpu_model = "cortex-a53",
> >          .memmap = a15memmap,
> >          .irqmap = a15irqmap,
> > +        .class_name = TYPE_AARCH64_CPU,
> >      },
> >      {
> >          .cpu_model = "cortex-a57",
> >          .memmap = a15memmap,
> >          .irqmap = a15irqmap,
> > +        .class_name = TYPE_AARCH64_CPU,
> >      },
> >      {
> >          .cpu_model = "host",
> >          .memmap = a15memmap,
> >          .irqmap = a15irqmap,
> > +        .class_name = TYPE_ARM_CPU,
> >      },
> >  };
> >
> > @@ -228,7 +236,6 @@ static void fdt_add_psci_node(const VirtBoardInfo
> *vbi)
> >      if (armcpu->psci_version == 2) {
> >          const char comp[] = "arm,psci-0.2\0arm,psci";
> >          qemu_fdt_setprop(fdt, "/psci", "compatible", comp,
> sizeof(comp));
> > -
> >          cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
> >          if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
> >              cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
> > @@ -241,7 +248,6 @@ static void fdt_add_psci_node(const VirtBoardInfo
> *vbi)
> >          }
> >      } else {
> >          qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
> > -
> >          cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
> >          cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
> >          cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
> > @@ -274,6 +280,12 @@ static void fdt_add_timer_nodes(const VirtBoardInfo
> *vbi, int gictype)
> >          irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
> >                               GIC_FDT_IRQ_PPI_CPU_WIDTH,
> >                               (1 << vbi->smp_cpus) - 1);
> > +    } else if (gictype == 3) {
> > +        uint32_t max;
> > +        /* Argument is 32 bit but 8 bits are reserved for flags */
> > +        max = (vbi->smp_cpus >= 24) ? 24 : vbi->smp_cpus;
> > +        irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
> > +                             GICV3_FDT_IRQ_PPI_CPU_WIDTH, (1 << max) -
> 1);
> >      }
> >
> >      qemu_fdt_add_subnode(vbi->fdt, "/timer");
> > @@ -429,12 +441,32 @@ static void create_gic(VirtBoardInfo *vbi,
> qemu_irq *pic, int type, bool
> > secure)
> >      gicdev = qdev_create(NULL, gictype);
> >      qdev_prop_set_uint32(gicdev, "revision", type);
> >      qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
> > +
> > +#ifdef TARGET_AARCH64
> > +    if (type == 3) {
> > +        qdev_prop_set_uint32(gicdev, "len-mp-affinity", smp_cpus);
> > +        /* Connect GIC to CPU */
> > +        for (i = 0; i < smp_cpus; i++) {
> > +            char *propname;
> > +            CPUState *cpu = qemu_get_cpu(i);
> > +            ARMCPU *armcpu = ARM_CPU(cpu);
> > +            propname = g_strdup_printf("mp-affinity[%d]", i);
> > +            qdev_prop_set_uint64(gicdev, propname, armcpu->mp_affinity);
> > +            g_free(propname);
> > +        }
> > +    }
> > +#endif
> >      /* Note that the num-irq property counts both internal and external
> >       * interrupts; there are always 32 of the former (mandated by GIC
> spec).
> >       */
> >      qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
> >      if (!kvm_irqchip_in_kernel()) {
> > -        qdev_prop_set_bit(gicdev, "has-security-extensions", secure);
> > +        if (type == 3) {
> > +            /* AARCH64 has 4 security levels */
> > +            qdev_prop_set_uint8(gicdev, "security-levels", secure ? 1 :
> 0);
> > +        } else {
> > +            qdev_prop_set_bit(gicdev, "has-security-extensions",
> secure);
> > +        }
> >      }
> >      qdev_init_nofail(gicdev);
> >      gicbusdev = SYS_BUS_DEVICE(gicdev);
> > @@ -445,6 +477,16 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq
> *pic, int type, bool
> > secure)
> >          sysbus_mmio_map(gicbusdev, 1, vbi->memmap[VIRT_GIC_CPU].base);
> >      }
> >
> > +#ifdef TARGET_AARCH64
> > +    if (type == 3) {
> > +        /* Connect GIC to CPU */
> > +        for (i = 0; i < smp_cpus; i++) {
> > +            CPUState *cpu = qemu_get_cpu(i);
> > +            aarch64_registers_with_opaque_set(OBJECT(cpu), (void
> *)gicdev);
> > +        }
> > +    }
> > +#endif
> > +
> >      /* Wire the outputs from each CPU's generic timer to the
> >       * appropriate GIC PPI inputs, and the GIC's IRQ output to
> >       * the CPU's IRQ input.
> > @@ -466,7 +508,7 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq
> *pic, int type, bool
> > secure)
> >          for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
> >              qdev_connect_gpio_out(cpudev, irq,
> >                                    qdev_get_gpio_in(gicdev,
> > -                                                   ppibase +
> timer_irq[irq]));
> > +                                  ppibase + timer_irq[irq]));
> >          }
> >
> >          sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev,
> ARM_CPU_IRQ));
> > @@ -967,7 +1009,7 @@ static void machvirt_init(MachineState *machine)
> >      create_fdt(vbi);
> >
> >      for (n = 0; n < smp_cpus; n++) {
> > -        ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
> > +        ObjectClass *oc = cpu_class_by_name(vbi->class_name, cpustr[0]);
> >          CPUClass *cc = CPU_CLASS(oc);
> >          Object *cpuobj;
> >          Error *err = NULL;
> > @@ -1116,7 +1158,7 @@ static void virt_set_gic_version(Object *obj,
> const char *value, Error
> > **errp)
> >      }
> >  }
> >
> > -static void virt_instance_init(Object *obj)
> > +static void virt_instance_init_common(Object *obj, int32_t version)
> >  {
> >      VirtMachineState *vms = VIRT_MACHINE(obj);
> >
> > @@ -1140,8 +1182,7 @@ static void virt_instance_init(Object *obj)
> >                                      "Set on/off to enable/disable using
> "
> >                                      "physical address space above 32
> bits",
> >                                      NULL);
> > -    /* Default GIC type is v2 */
> > -    vms->gic_version = 2;
> > +    vms->gic_version = version;
> >      object_property_add_str(obj, "gic-version", virt_get_gic_version,
> >                          virt_set_gic_version, NULL);
> >      object_property_set_description(obj, "gic-version",
> > @@ -1149,6 +1190,12 @@ static void virt_instance_init(Object *obj)
> >                                      "Valid values are 2, 3 and host",
> NULL);
> >  }
> >
> > +static void virt_instance_init(Object *obj)
> > +{
> > +    /* Default GIC type is v2 */
> > +    virt_instance_init_common(obj, 2);
> > +}
> > +
> >  static void virt_class_init(ObjectClass *oc, void *data)
> >  {
> >      MachineClass *mc = MACHINE_CLASS(oc);
> > @@ -1174,9 +1221,33 @@ static const TypeInfo machvirt_info = {
> >      .class_init = virt_class_init,
> >  };
> >
> > +static void virtv3_instance_init(Object *obj)
> > +{
> > +    virt_instance_init_common(obj, 3);
> > +}
> > +
> > +static void virtv3_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +
> > +    mc->name = TYPE_VIRTV3_MACHINE;
> > +    mc->desc = "ARM Virtual Machine with GICv3",
> > +    mc->init = machvirt_init;
> > +}
> > +
> > +static const TypeInfo machvirtv3_info = {
> > +    .name = TYPE_VIRTV3_MACHINE,
> > +    .parent = TYPE_VIRT_MACHINE,
> > +    .instance_size = sizeof(VirtMachineState),
> > +    .instance_init = virtv3_instance_init,
> > +    .class_size = sizeof(VirtMachineClass),
> > +    .class_init = virtv3_class_init,
> > +};
> > +
> >  static void machvirt_machine_init(void)
> >  {
> >      type_register_static(&machvirt_info);
> > +    type_register_static(&machvirtv3_info);
> >  }
>
>  As i said before, this stuff is simply not needed.
>
> >
> >  machine_init(machvirt_machine_init);
> > diff --git a/include/hw/arm/fdt.h b/include/hw/arm/fdt.h
> > index c3d5015..ad8f85c 100644
> > --- a/include/hw/arm/fdt.h
> > +++ b/include/hw/arm/fdt.h
> > @@ -30,5 +30,7 @@
> >
> >  #define GIC_FDT_IRQ_PPI_CPU_START 8
> >  #define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
> > +#define GICV3_FDT_IRQ_PPI_CPU_WIDTH 24
> > +
> >
> >  #endif
> > diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
> > index f464586..53ff50a 100644
> > --- a/include/hw/arm/virt.h
> > +++ b/include/hw/arm/virt.h
> > @@ -46,6 +46,7 @@ enum {
> >      VIRT_CPUPERIPHS,
> >      VIRT_GIC_DIST,
> >      VIRT_GIC_CPU,
> > +    VIRT_GIC_DIST_SPI = VIRT_GIC_CPU,
> >      VIRT_GIC_V2M,
> >      VIRT_GIC_ITS,
> >      VIRT_GIC_REDIST,
> > diff --git a/target-arm/machine.c b/target-arm/machine.c
> > index 36a0d15..33f28be 100644
> > --- a/target-arm/machine.c
> > +++ b/target-arm/machine.c
> > @@ -341,7 +341,12 @@ const char *gicv3_class_name(void)
> >  #endif
> >      } else {
> >          /* TODO: Software emulation is not implemented yet */
> > -        error_report("KVM is currently required for GICv3 emulation\n");
> > +#ifdef TARGET_AARCH64
> > +        return "arm_gicv3";
>
>  Peter told me, there is a policy to use dash ("-") in class names. So
> "arm-gicv3".
>  By the way, why does it depend on TARGET_AARCH64? Actually, TARGET_ARM
> and TARGET_AARCH64 are the same. You can make both emulators
> running both 64- and 32-bit code. KVM code depends on TARGET_AARCH64 only
> because some definitions are missing on 32-bit kernels.
> You don't have this restriction, so you don't need this #ifdef.
>

O.K. I'll change to dash.
GICV3 is accessed by system instructions that exists only in ARCH64.


> > +#else
> > +        error_report("KVM GICv3 acceleration is not supported on this "
> > +                     "platform\n");
>
>  Why "KVM" here? Well, rubbish anyway because of the above. :)
>
> > +#endif
> >      }
> >
> >      exit(1);
> > --
> > 1.9.1
>
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
>
>

Reply via email to