qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH target-arm v8 04/14] arm: xlnx-zynqmp: Add GIC


From: Edgar E. Iglesias
Subject: Re: [Qemu-devel] [PATCH target-arm v8 04/14] arm: xlnx-zynqmp: Add GIC
Date: Mon, 11 May 2015 14:54:41 +1000
User-agent: Mutt/1.5.21 (2010-09-15)

On Thu, May 07, 2015 at 05:57:12PM -0700, Peter Crosthwaite wrote:
> Add the GIC and connect IRQ outputs to the CPUs. The GIC regions are
> under-decoded through a 64k address region so implement aliases
> accordingly.
> 
> Signed-off-by: Peter Crosthwaite <address@hidden>
> ---
> changed since v7:
> Made GIC region size definition board specific
> changed since v6:
> Added aliases.
> changed since v5:
> Make commit msg body standalone
> Add reset-cbar configuration
> 
>  hw/arm/xlnx-zynqmp.c         | 59 
> ++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/arm/xlnx-zynqmp.h | 14 +++++++++++
>  2 files changed, 73 insertions(+)
> 
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index ec0ebaa..a8ab7e7 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -16,6 +16,23 @@
>   */
>  
>  #include "hw/arm/xlnx-zynqmp.h"
> +#include "exec/address-spaces.h"
> +
> +#define GIC_NUM_SPI_INTR 128


Is this correct? I think it should be 160.



> +
> +#define GIC_BASE_ADDR       0xf9000000
> +#define GIC_DIST_ADDR       0xf9010000
> +#define GIC_CPU_ADDR        0xf9020000
> +
> +typedef struct XlnxZynqMPGICRegion {
> +    int region_index;
> +    uint32_t address;
> +} XlnxZynqMPGICRegion;
> +
> +static const XlnxZynqMPGICRegion xlnx_zynqmp_gic_regions[] = {
> +    { .region_index = 0, .address = GIC_DIST_ADDR, },
> +    { .region_index = 1, .address = GIC_CPU_ADDR,  },
> +};
>  
>  static void xlnx_zynqmp_init(Object *obj)
>  {
> @@ -28,14 +45,46 @@ static void xlnx_zynqmp_init(Object *obj)
>          object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpu[i]),
>                                    &error_abort);
>      }
> +
> +    object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
> +    qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
>  }
>  
>  static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
>  {
>      XlnxZynqMPState *s = XLNX_ZYNQMP(dev);
> +    MemoryRegion *system_memory = get_system_memory();
>      uint8_t i;
>      Error *err = NULL;
>  
> +    qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32);
> +    qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2);
> +    qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQMP_NUM_CPUS);
> +    object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
> +    if (err) {
> +        error_propagate((errp), (err));
> +        return;
> +    }
> +    assert(ARRAY_SIZE(xlnx_zynqmp_gic_regions) == XLNX_ZYNQMP_GIC_REGIONS);
> +    for (i = 0; i < XLNX_ZYNQMP_GIC_REGIONS; i++) {
> +        SysBusDevice *gic = SYS_BUS_DEVICE(&s->gic);
> +        const XlnxZynqMPGICRegion *r = &xlnx_zynqmp_gic_regions[i];
> +        MemoryRegion *mr = sysbus_mmio_get_region(gic, r->region_index);
> +        uint32_t addr = r->address;
> +        int j;
> +
> +        sysbus_mmio_map(gic, r->region_index, addr);
> +
> +        for (j = 0; j < XLNX_ZYNQMP_GIC_ALIASES; j++) {
> +            MemoryRegion *alias = &s->gic_mr[i][j];
> +
> +            addr += XLNX_ZYNQMP_GIC_REGION_SIZE;
> +            memory_region_init_alias(alias, OBJECT(s), "zynqmp-gic-alias", 
> mr,
> +                                     0, XLNX_ZYNQMP_GIC_REGION_SIZE);
> +            memory_region_add_subregion(system_memory, addr, alias);
> +        }
> +    }
> +
>      for (i = 0; i < XLNX_ZYNQMP_NUM_CPUS; i++) {
>          object_property_set_int(OBJECT(&s->cpu[i]), QEMU_PSCI_CONDUIT_SMC,
>                                  "psci-conduit", &error_abort);
> @@ -45,11 +94,21 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
> **errp)
>                                       "start-powered-off", &error_abort);
>          }
>  
> +        object_property_set_int(OBJECT(&s->cpu[i]), GIC_BASE_ADDR,
> +                                "reset-cbar", &err);
> +        if (err) {
> +            error_propagate((errp), (err));
> +            return;
> +        }
> +
>          object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err);
>          if (err) {
>              error_propagate((errp), (err));
>              return;
>          }
> +
> +        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i,
> +                           qdev_get_gpio_in(DEVICE(&s->cpu[i]), 
> ARM_CPU_IRQ));
>      }
>  }
>  
> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
> index 62f6b6f..719bc8b 100644
> --- a/include/hw/arm/xlnx-zynqmp.h
> +++ b/include/hw/arm/xlnx-zynqmp.h
> @@ -19,6 +19,7 @@
>  
>  #include "qemu-common.h"
>  #include "hw/arm/arm.h"
> +#include "hw/intc/arm_gic.h"
>  
>  #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
>  #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \
> @@ -26,12 +27,25 @@
>  
>  #define XLNX_ZYNQMP_NUM_CPUS 4
>  
> +#define XLNX_ZYNQMP_GIC_REGIONS 2
> +
> +/* ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k 
> offsets
> + * and under-decodes the 64k region. This mirrors the 4k regions to every 4k
> + * aligned address in the 64k region. To implement each GIC region needs a
> + * number of memory region aliases.
> + */
> +
> +#define XLNX_ZYNQMP_GIC_REGION_SIZE 0x4000
> +#define XLNX_ZYNQMP_GIC_ALIASES     (0x10000 / XLNX_ZYNQMP_GIC_REGION_SIZE - 
> 1)
> +
>  typedef struct XlnxZynqMPState {
>      /*< private >*/
>      DeviceState parent_obj;
>  
>      /*< public >*/
>      ARMCPU cpu[XLNX_ZYNQMP_NUM_CPUS];
> +    GICState gic;
> +    MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES];
>  }  XlnxZynqMPState;
>  
>  #define XLNX_ZYNQMP_H
> -- 
> 2.4.0.3.ge0ccc3b.dirty
> 



reply via email to

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