Re: [Qemu-devel] [PATCH v1 11/12] hw/arm: versal: Add a model of Xilinx Versal SoC

2018-10-08 Thread Edgar E. Iglesias
On Mon, Oct 08, 2018 at 02:19:09PM +0100, Peter Maydell wrote:
> On 3 October 2018 at 16:07, Edgar E. Iglesias  
> wrote:
> > From: "Edgar E. Iglesias" 
> >
> > Add a model of Xilinx Versal SoC.
> >
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  default-configs/aarch64-softmmu.mak |   1 +
> >  hw/arm/Makefile.objs|   1 +
> >  hw/arm/xlnx-versal.c| 339 
> > 
> >  include/hw/arm/xlnx-versal.h| 122 +
> >  4 files changed, 463 insertions(+)
> >  create mode 100644 hw/arm/xlnx-versal.c
> >  create mode 100644 include/hw/arm/xlnx-versal.h
> >
> 
> 
> > +#define XLNX_VERSAL_ACPU_TYPE "cortex-a72" "-" TYPE_ARM_CPU
> 
> ARM_CPU_TYPE_NAME("cortex-a72") is preferable to hand-assembling
> the type name like this.

Fixed for v2.


> 
> > +#define GEM_REVISION0x40070106
> > +
> 
> > +for (i = 0; i < nr_apu_cpus; i++) {
> > +DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
> > +int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
> > +qemu_irq maint_irq;
> > +int ti;
> > +/* Mapping from the output timer irq lines from the CPU to the
> > + * GIC PPI inputs we use for the virt board.
> > + */
> 
> This isn't the virt board :-) -- cut-n-pasted comment ?

Fixed for v2.


> 
> > +const int timer_irq[] = {
> > +[GTIMER_PHYS] = VERSAL_TIMER_NS_EL1_IRQ,
> > +[GTIMER_VIRT] = VERSAL_TIMER_VIRT_IRQ,
> > +[GTIMER_HYP]  = VERSAL_TIMER_NS_EL2_IRQ,
> > +[GTIMER_SEC]  = VERSAL_TIMER_S_EL1_IRQ,
> > +};
> > +
> > +for (ti = 0; ti < ARRAY_SIZE(timer_irq); ti++) {
> > +qdev_connect_gpio_out(cpudev, ti,
> > +  qdev_get_gpio_in(gicdev,
> > +   ppibase + 
> > timer_irq[ti]));
> > +}
> > +maint_irq = qdev_get_gpio_in(gicdev,
> > +ppibase + VERSAL_GIC_MAINT_IRQ);
> > +qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
> > +0, maint_irq);
> > +sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, 
> > ARM_CPU_IRQ));
> > +sysbus_connect_irq(gicbusdev, i + nr_apu_cpus,
> > +   qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
> > +sysbus_connect_irq(gicbusdev, i + 2 * nr_apu_cpus,
> > +   qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
> > +sysbus_connect_irq(gicbusdev, i + 3 * nr_apu_cpus,
> > +   qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
> > +}
> > +
> > +for (i = 0; i < XLNX_VERSAL_NR_IRQS; i++) {
> > +pic[i] = qdev_get_gpio_in(gicdev, i);
> > +}
> 
> > +/* This takes the board allocated linear DDR memory and creates aliases
> > + * for each split DDR range/apperture on the Versal address map.
> 
> "aperture"

Fixed


> 
> 
> 
> > +static void versal_realize(DeviceState *dev, Error **errp)
> > +{
> > +Versal *s = XLNX_VERSAL(dev);
> > +qemu_irq pic[XLNX_VERSAL_NR_IRQS];
> > +
> > +versal_create_apu_cpus(s, errp);
> > +versal_create_apu_gic(s, pic, errp);
> > +versal_create_uarts(s, pic);
> > +versal_create_gems(s, pic);
> > +versal_map_ddr(s);
> > +versal_unimp(s);
> > +
> > +/* Create the OCM.  */
> > +memory_region_init_ram(>lpd.mr_ocm, OBJECT(s), "ocm",
> > +   MM_OCM_SIZE, _fatal);
> 
> What's an OCM? Is it really memory, or is this a stub for something?


I've changed the comment to spell out that it's an On Chip Memory.


> 
> > +
> > +memory_region_add_subregion_overlap(>mr_ps, MM_OCM, >lpd.mr_ocm, 
> > 0);
> > +memory_region_add_subregion_overlap(>fpd.apu.mr, 0, >mr_ps, 0);
> > +}
> > +
> > +static void versal_init(Object *obj)
> > +{
> > +Versal *s = XLNX_VERSAL(obj);
> > +
> > +memory_region_init(>fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
> > +memory_region_init(>mr_ps, obj, "mr-ps-switch", UINT64_MAX);
> > +}
> > +
> > +static const VMStateDescription versal_vmstate = {
> > +.name = "xlnx-ve",
> > +.version_id = 1,
> > +.minimum_version_id = 1,
> > +.fields = (VMStateField[]) {
> > +/* FIXME.  */
> 
> Stray FIXME comment -- I think the answer may be "the
> SoC object has no state of its own so needs neither a
> vmsd nor a reset method" ? (If so and if you drop them,
> do put a comment in the class init about why they're not
> provided. Some day we may have a mechanism for a device
> to explicitly say "I need no vmstate" so we can assert if
> none is provided.)

Thanks, I'll do that.


> 
> > +VMSTATE_END_OF_LIST()
> > +}
> > +};
> > +
> > +static Property versal_properties[] = {
> > +DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION,
> > + MemoryRegion *),
> > +DEFINE_PROP_UINT32("psci-conduit", Versal, cfg.psci_conduit, 

Re: [Qemu-devel] [PATCH v1 11/12] hw/arm: versal: Add a model of Xilinx Versal SoC

2018-10-08 Thread Peter Maydell
On 3 October 2018 at 16:07, Edgar E. Iglesias  wrote:
> From: "Edgar E. Iglesias" 
>
> Add a model of Xilinx Versal SoC.
>
> Signed-off-by: Edgar E. Iglesias 
> ---
>  default-configs/aarch64-softmmu.mak |   1 +
>  hw/arm/Makefile.objs|   1 +
>  hw/arm/xlnx-versal.c| 339 
> 
>  include/hw/arm/xlnx-versal.h| 122 +
>  4 files changed, 463 insertions(+)
>  create mode 100644 hw/arm/xlnx-versal.c
>  create mode 100644 include/hw/arm/xlnx-versal.h
>


> +#define XLNX_VERSAL_ACPU_TYPE "cortex-a72" "-" TYPE_ARM_CPU

ARM_CPU_TYPE_NAME("cortex-a72") is preferable to hand-assembling
the type name like this.

> +#define GEM_REVISION0x40070106
> +

> +for (i = 0; i < nr_apu_cpus; i++) {
> +DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
> +int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
> +qemu_irq maint_irq;
> +int ti;
> +/* Mapping from the output timer irq lines from the CPU to the
> + * GIC PPI inputs we use for the virt board.
> + */

This isn't the virt board :-) -- cut-n-pasted comment ?

> +const int timer_irq[] = {
> +[GTIMER_PHYS] = VERSAL_TIMER_NS_EL1_IRQ,
> +[GTIMER_VIRT] = VERSAL_TIMER_VIRT_IRQ,
> +[GTIMER_HYP]  = VERSAL_TIMER_NS_EL2_IRQ,
> +[GTIMER_SEC]  = VERSAL_TIMER_S_EL1_IRQ,
> +};
> +
> +for (ti = 0; ti < ARRAY_SIZE(timer_irq); ti++) {
> +qdev_connect_gpio_out(cpudev, ti,
> +  qdev_get_gpio_in(gicdev,
> +   ppibase + timer_irq[ti]));
> +}
> +maint_irq = qdev_get_gpio_in(gicdev,
> +ppibase + VERSAL_GIC_MAINT_IRQ);
> +qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
> +0, maint_irq);
> +sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, 
> ARM_CPU_IRQ));
> +sysbus_connect_irq(gicbusdev, i + nr_apu_cpus,
> +   qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
> +sysbus_connect_irq(gicbusdev, i + 2 * nr_apu_cpus,
> +   qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
> +sysbus_connect_irq(gicbusdev, i + 3 * nr_apu_cpus,
> +   qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
> +}
> +
> +for (i = 0; i < XLNX_VERSAL_NR_IRQS; i++) {
> +pic[i] = qdev_get_gpio_in(gicdev, i);
> +}

> +/* This takes the board allocated linear DDR memory and creates aliases
> + * for each split DDR range/apperture on the Versal address map.

"aperture"



> +static void versal_realize(DeviceState *dev, Error **errp)
> +{
> +Versal *s = XLNX_VERSAL(dev);
> +qemu_irq pic[XLNX_VERSAL_NR_IRQS];
> +
> +versal_create_apu_cpus(s, errp);
> +versal_create_apu_gic(s, pic, errp);
> +versal_create_uarts(s, pic);
> +versal_create_gems(s, pic);
> +versal_map_ddr(s);
> +versal_unimp(s);
> +
> +/* Create the OCM.  */
> +memory_region_init_ram(>lpd.mr_ocm, OBJECT(s), "ocm",
> +   MM_OCM_SIZE, _fatal);

What's an OCM? Is it really memory, or is this a stub for something?

> +
> +memory_region_add_subregion_overlap(>mr_ps, MM_OCM, >lpd.mr_ocm, 
> 0);
> +memory_region_add_subregion_overlap(>fpd.apu.mr, 0, >mr_ps, 0);
> +}
> +
> +static void versal_init(Object *obj)
> +{
> +Versal *s = XLNX_VERSAL(obj);
> +
> +memory_region_init(>fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
> +memory_region_init(>mr_ps, obj, "mr-ps-switch", UINT64_MAX);
> +}
> +
> +static const VMStateDescription versal_vmstate = {
> +.name = "xlnx-ve",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.fields = (VMStateField[]) {
> +/* FIXME.  */

Stray FIXME comment -- I think the answer may be "the
SoC object has no state of its own so needs neither a
vmsd nor a reset method" ? (If so and if you drop them,
do put a comment in the class init about why they're not
provided. Some day we may have a mechanism for a device
to explicitly say "I need no vmstate" so we can assert if
none is provided.)

> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
> +static Property versal_properties[] = {
> +DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION,
> + MemoryRegion *),
> +DEFINE_PROP_UINT32("psci-conduit", Versal, cfg.psci_conduit, 0),
> +DEFINE_PROP_END_OF_LIST()
> +};
> +
> +static void versal_reset(DeviceState *dev)
> +{
> +}
> +
> +static void versal_class_init(ObjectClass *klass, void *data)
> +{
> +DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +dc->realize = versal_realize;
> +dc->vmsd = _vmstate;
> +dc->props = versal_properties;
> +dc->reset = versal_reset;
> +}

Looks good otherwise.

thanks
-- PMM



Re: [Qemu-devel] [PATCH v1 11/12] hw/arm: versal: Add a model of Xilinx Versal SoC

2018-10-05 Thread Philippe Mathieu-Daudé
On 03/10/2018 17:07, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" 
> 
> Add a model of Xilinx Versal SoC.
> 
> Signed-off-by: Edgar E. Iglesias 
> ---
>  default-configs/aarch64-softmmu.mak |   1 +
>  hw/arm/Makefile.objs|   1 +
>  hw/arm/xlnx-versal.c| 339 
> 
>  include/hw/arm/xlnx-versal.h| 122 +
>  4 files changed, 463 insertions(+)
>  create mode 100644 hw/arm/xlnx-versal.c
>  create mode 100644 include/hw/arm/xlnx-versal.h
> 
> diff --git a/default-configs/aarch64-softmmu.mak 
> b/default-configs/aarch64-softmmu.mak
> index 6f790f0..4ea9add 100644
> --- a/default-configs/aarch64-softmmu.mak
> +++ b/default-configs/aarch64-softmmu.mak
> @@ -8,4 +8,5 @@ CONFIG_DDC=y
>  CONFIG_DPCD=y
>  CONFIG_XLNX_ZYNQMP=y
>  CONFIG_XLNX_ZYNQMP_ARM=y
> +CONFIG_XLNX_VERSAL=y
>  CONFIG_ARM_SMMUV3=y
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 5f88062..ec21d9b 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -26,6 +26,7 @@ obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
>  obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
>  obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
>  obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o
> +obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o
>  obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
>  obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
>  obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> new file mode 100644
> index 000..c12fc85
> --- /dev/null
> +++ b/hw/arm/xlnx-versal.c
> @@ -0,0 +1,339 @@
> +/*
> + * Xilinx Versal SoC model.
> + *
> + * Copyright (c) 2018 Xilinx Inc.
> + * Written by Edgar E. Iglesias
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 or
> + * (at your option) any later version.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "qemu-common.h"
> +#include "qemu/log.h"
> +#include "hw/sysbus.h"
> +#include "net/net.h"
> +#include "sysemu/sysemu.h"
> +#include "sysemu/kvm.h"
> +#include "hw/arm/arm.h"
> +#include "kvm_arm.h"
> +#include "hw/misc/unimp.h"
> +#include "hw/intc/arm_gicv3_common.h"
> +#include "hw/arm/xlnx-versal.h"
> +
> +#define XLNX_VERSAL_ACPU_TYPE "cortex-a72" "-" TYPE_ARM_CPU
> +#define GEM_REVISION0x40070106
> +
> +static void versal_create_apu_cpus(Versal *s, Error **errp)
> +{
> +int i;
> +
> +for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
> +Object *obj;
> +char *name;
> +
> +obj = object_new(XLNX_VERSAL_ACPU_TYPE);
> +if (!obj) {
> +/* Secondary CPUs start in PSCI powered-down state */
> +error_setg(errp, "Unable to create apu.cpu[%d] of type %s",
> +   i, XLNX_VERSAL_ACPU_TYPE);
> +return;
> +}
> +
> +name = g_strdup_printf("apu-cpu[%d]", i);
> +object_property_add_child(OBJECT(s), name, obj, _fatal);
> +g_free(name);
> +
> +object_property_set_int(obj, s->cfg.psci_conduit,
> +"psci-conduit", _abort);
> +if (i) {
> +object_property_set_bool(obj, true,
> + "start-powered-off", _abort);
> +}
> +
> +object_property_set_int(obj, ARRAY_SIZE(s->fpd.apu.cpu),
> +"core-count", _abort);
> +object_property_set_link(obj, OBJECT(>fpd.apu.mr), "memory",
> + _abort);
> +object_property_set_bool(obj, true, "realized", _fatal);
> +s->fpd.apu.cpu[i] = ARM_CPU(obj);
> +}
> +}
> +
> +static void versal_create_apu_gic(Versal *s, qemu_irq *pic, Error **errp)
> +{
> +static const uint64_t addrs[] = {
> +MM_GIC_APU_DIST_MAIN,
> +MM_GIC_APU_REDIST_0
> +};
> +SysBusDevice *gicbusdev;
> +DeviceState *gicdev;
> +int nr_apu_cpus = ARRAY_SIZE(s->fpd.apu.cpu);
> +int i;
> +
> +sysbus_init_child_obj(OBJECT(s), "apu-gic",
> +  >fpd.apu.gic, sizeof(s->fpd.apu.gic),
> +  gicv3_class_name());
> +gicbusdev = SYS_BUS_DEVICE(>fpd.apu.gic);
> +gicdev = DEVICE(>fpd.apu.gic);
> +qdev_prop_set_uint32(gicdev, "revision", 3);
> +qdev_prop_set_uint32(gicdev, "num-cpu", 2);
> +qdev_prop_set_uint32(gicdev, "num-irq", XLNX_VERSAL_NR_IRQS + 32);
> +qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
> +qdev_prop_set_uint32(gicdev, "redist-region-count[0]", 2);
> +if (!kvm_irqchip_in_kernel()) {
> +qdev_prop_set_bit(gicdev, "has-security-extensions", true);
> +}
> +
> +object_property_set_bool(OBJECT(>fpd.apu.gic), true, "realized", 
> errp);
> +
> +for (i = 0; i < ARRAY_SIZE(addrs); i++) {
> +MemoryRegion *mr;
> +
> +mr =