qemu-arm
[Top][All Lists]
Advanced

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

Re: [Qemu-arm] [PATCH v4 19/20] xlnx-zynqmp: Improve GIC wiring and MMIO


From: Edgar E. Iglesias
Subject: Re: [Qemu-arm] [PATCH v4 19/20] xlnx-zynqmp: Improve GIC wiring and MMIO mapping
Date: Sat, 14 Jul 2018 19:42:51 +0200
User-agent: NeoMutt/20170609 (1.8.3)

On Sat, Jul 14, 2018 at 07:16:00PM +0200, Luc Michel wrote:
> This commit improve the way the GIC is realized and connected in the
> ZynqMP SoC. The security extensions are enabled only if requested in the
> machine state. The same goes for the virtualization extensions.
> 
> All the GIC to APU CPU(s) IRQ lines are now connected, including FIQ,
> vIRQ and vFIQ. The missing CPU to GIC timers IRQ connections are also
> added (HYP and SEC timers).
> 
> The GIC maintenance IRQs are back-wired to the correct GIC PPIs.
> 
> Finally, the MMIO mappings are reworked to take into account the ZynqMP
> specifics. The GIC (v)CPU interface is aliased 16 times:
>   * for the first 0x1000 bytes from 0xf9010000 to 0xf901f000
>   * for the second 0x1000 bytes from 0xf9020000 to 0xf902f000
> Mappings of the virtual interface and virtual CPU interface are mapped
> only when virtualization extensions are requested. The
> XlnxZynqMPGICRegion struct has been enhanced to be able to catch all
> this information.
> 
> Signed-off-by: Luc Michel <address@hidden>

Looks good to me!

Reviewed-by: Edgar E. Iglesias <address@hidden>



> ---
>  hw/arm/xlnx-zynqmp.c         | 92 ++++++++++++++++++++++++++++++++----
>  include/hw/arm/xlnx-zynqmp.h |  4 +-
>  2 files changed, 86 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index 29df35fb75..42c29b8d06 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -29,12 +29,17 @@
>  
>  #define ARM_PHYS_TIMER_PPI  30
>  #define ARM_VIRT_TIMER_PPI  27
> +#define ARM_HYP_TIMER_PPI   26
> +#define ARM_SEC_TIMER_PPI   29
> +#define GIC_MAINTENANCE_PPI 25
>  
>  #define GEM_REVISION        0x40070106
>  
>  #define GIC_BASE_ADDR       0xf9000000
>  #define GIC_DIST_ADDR       0xf9010000
>  #define GIC_CPU_ADDR        0xf9020000
> +#define GIC_VIFACE_ADDR     0xf9040000
> +#define GIC_VCPU_ADDR       0xf9060000
>  
>  #define SATA_INTR           133
>  #define SATA_ADDR           0xFD0C0000
> @@ -111,11 +116,54 @@ static const int adma_ch_intr[XLNX_ZYNQMP_NUM_ADMA_CH] 
> = {
>  typedef struct XlnxZynqMPGICRegion {
>      int region_index;
>      uint32_t address;
> +    uint32_t offset;
> +    bool virt;
>  } XlnxZynqMPGICRegion;
>  
>  static const XlnxZynqMPGICRegion xlnx_zynqmp_gic_regions[] = {
> -    { .region_index = 0, .address = GIC_DIST_ADDR, },
> -    { .region_index = 1, .address = GIC_CPU_ADDR,  },
> +    /* Distributor */
> +    {
> +        .region_index = 0,
> +        .address = GIC_DIST_ADDR,
> +        .offset = 0,
> +        .virt = false
> +    },
> +
> +    /* CPU interface */
> +    {
> +        .region_index = 1,
> +        .address = GIC_CPU_ADDR,
> +        .offset = 0,
> +        .virt = false
> +    },
> +    {
> +        .region_index = 1,
> +        .address = GIC_CPU_ADDR + 0x10000,
> +        .offset = 0x1000,
> +        .virt = false
> +    },
> +
> +    /* Virtual interface */
> +    {
> +        .region_index = 2,
> +        .address = GIC_VIFACE_ADDR,
> +        .offset = 0,
> +        .virt = true
> +    },
> +
> +    /* Virtual CPU interface */
> +    {
> +        .region_index = 3,
> +        .address = GIC_VCPU_ADDR,
> +        .offset = 0,
> +        .virt = true
> +    },
> +    {
> +        .region_index = 3,
> +        .address = GIC_VCPU_ADDR + 0x10000,
> +        .offset = 0x1000,
> +        .virt = true
> +    },
>  };
>  
>  static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index)
> @@ -286,6 +334,9 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
> **errp)
>      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", num_apus);
> +    qdev_prop_set_bit(DEVICE(&s->gic), "has-security-extensions", s->secure);
> +    qdev_prop_set_bit(DEVICE(&s->gic),
> +                      "has-virtualization-extensions", s->virt);
>  
>      /* Realize APUs before realizing the GIC. KVM requires this.  */
>      for (i = 0; i < num_apus; i++) {
> @@ -330,19 +381,23 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
> **errp)
>      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);
> +        MemoryRegion *mr;
>          uint32_t addr = r->address;
>          int j;
>  
> -        sysbus_mmio_map(gic, r->region_index, addr);
> +        if (r->virt && !s->virt) {
> +            continue;
> +        }
>  
> +        mr = sysbus_mmio_get_region(gic, r->region_index);
>          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);
> +                                     r->offset, XLNX_ZYNQMP_GIC_REGION_SIZE);
>              memory_region_add_subregion(system_memory, addr, alias);
> +
> +            addr += XLNX_ZYNQMP_GIC_REGION_SIZE;
>          }
>      }
>  
> @@ -352,12 +407,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
> **errp)
>          sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i,
>                             qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]),
>                                              ARM_CPU_IRQ));
> +        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus,
> +                           qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]),
> +                                            ARM_CPU_FIQ));
> +        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus * 2,
> +                           qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]),
> +                                            ARM_CPU_VIRQ));
> +        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus * 3,
> +                           qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]),
> +                                            ARM_CPU_VFIQ));
>          irq = qdev_get_gpio_in(DEVICE(&s->gic),
>                                 arm_gic_ppi_index(i, ARM_PHYS_TIMER_PPI));
> -        qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 0, irq);
> +        qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), GTIMER_PHYS, irq);
>          irq = qdev_get_gpio_in(DEVICE(&s->gic),
>                                 arm_gic_ppi_index(i, ARM_VIRT_TIMER_PPI));
> -        qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq);
> +        qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), GTIMER_VIRT, irq);
> +        irq = qdev_get_gpio_in(DEVICE(&s->gic),
> +                               arm_gic_ppi_index(i, ARM_HYP_TIMER_PPI));
> +        qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), GTIMER_HYP, irq);
> +        irq = qdev_get_gpio_in(DEVICE(&s->gic),
> +                               arm_gic_ppi_index(i, ARM_SEC_TIMER_PPI));
> +        qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), GTIMER_SEC, irq);
> +
> +        if (s->virt) {
> +            irq = qdev_get_gpio_in(DEVICE(&s->gic),
> +                                   arm_gic_ppi_index(i, 
> GIC_MAINTENANCE_PPI));
> +            sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus * 4, 
> irq);
> +        }
>      }
>  
>      if (s->has_rpu) {
> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
> index 82b6ec2486..98f925ab84 100644
> --- a/include/hw/arm/xlnx-zynqmp.h
> +++ b/include/hw/arm/xlnx-zynqmp.h
> @@ -53,7 +53,7 @@
>  #define XLNX_ZYNQMP_OCM_RAM_0_ADDRESS 0xFFFC0000
>  #define XLNX_ZYNQMP_OCM_RAM_SIZE 0x10000
>  
> -#define XLNX_ZYNQMP_GIC_REGIONS 2
> +#define XLNX_ZYNQMP_GIC_REGIONS 6
>  
>  /* 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
> @@ -62,7 +62,7 @@
>   */
>  
>  #define XLNX_ZYNQMP_GIC_REGION_SIZE 0x1000
> -#define XLNX_ZYNQMP_GIC_ALIASES     (0x10000 / XLNX_ZYNQMP_GIC_REGION_SIZE - 
> 1)
> +#define XLNX_ZYNQMP_GIC_ALIASES     (0x10000 / XLNX_ZYNQMP_GIC_REGION_SIZE)
>  
>  #define XLNX_ZYNQMP_MAX_LOW_RAM_SIZE    0x80000000ull
>  
> -- 
> 2.18.0
> 
> 



reply via email to

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