From: Diana Craciun <diana.craciun@freescale.com>
To: Pavel Fedin <p.fedin@samsung.com>, qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Shlomo Pongratz <shlomopongratz@gmail.com>,
Eric Auger <eric.auger@linaro.org>,
Christoffer Dall <christoffer.dall@linaro.org>,
Shlomo Pongratz <shlomo.pongratz@huawei.com>
Subject: Re: [Qemu-devel] [PATCH v4 5/5] Add gicversion option to virt machine
Date: Wed, 15 Jul 2015 17:44:07 +0300 [thread overview]
Message-ID: <55A671B7.2010808@freescale.com> (raw)
In-Reply-To: <0c1f9bfc5a989591cffd59fd6b219cc09ac0b42b.1436859955.git.p.fedin@samsung.com>
Hi,
On 07/14/2015 10:54 AM, Pavel Fedin wrote:
> Set kernel_irqchip_type according to value of the option and pass it
> around where necessary. Instantiate devices and fdt nodes according
> to the choice.
>
> mac_cpus for virt machine increased to 64. GICv2 compatibility check
> happens inside arm_gic_common_realize().
>
> Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
> ---
> hw/arm/virt.c | 135 ++++++++++++++++++++++++++++++++++++++++++--------
> include/hw/arm/fdt.h | 2 +-
> include/hw/arm/virt.h | 6 ++-
> 3 files changed, 120 insertions(+), 23 deletions(-)
>
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 2e7d858..df69dc8 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -48,6 +48,8 @@
> #include "hw/arm/sysbus-fdt.h"
> #include "hw/platform-bus.h"
> #include "hw/arm/fdt.h"
> +#include "linux/kvm.h" /* For KVM_DEV_TYPE_ARM_VGIC_V{2|3} */
> +#include "qapi/visitor.h"
>
> /* Number of external interrupt lines to configure the GIC with */
> #define NUM_IRQS 256
> @@ -67,6 +69,7 @@ typedef struct VirtBoardInfo {
> uint32_t clock_phandle;
> uint32_t gic_phandle;
> uint32_t v2m_phandle;
> + const char *class_name;
> } VirtBoardInfo;
>
> typedef struct {
> @@ -80,6 +83,7 @@ typedef struct {
> } VirtMachineState;
>
> #define TYPE_VIRT_MACHINE "virt"
> +#define TYPE_VIRTV3_MACHINE "virt-v3"
> #define VIRT_MACHINE(obj) \
> OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE)
> #define VIRT_MACHINE_GET_CLASS(obj) \
> @@ -106,7 +110,12 @@ static const MemMapEntry a15memmap[] = {
> /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
> [VIRT_GIC_DIST] = { 0x08000000, 0x00010000 },
> [VIRT_GIC_CPU] = { 0x08010000, 0x00010000 },
> - [VIRT_GIC_V2M] = { 0x08020000, 0x00001000 },
> + [VIRT_GIC_V2M] = { 0x08020000, 0x00010000 },
> + /* On v3 VIRT_GIC_DIST_MBI and VIRT_ITS_CONTROL take place of
> + * VIRT_GIC_CPU and VIRT_GIC_V2M respectively
> + */
> + [VIRT_ITS_TRANSLATION] = { 0x08030000, 0x00010000 },
> + [VIRT_LPI] = { 0x08040000, 0x00800000 },
> [VIRT_UART] = { 0x09000000, 0x00001000 },
> [VIRT_RTC] = { 0x09010000, 0x00001000 },
> [VIRT_FW_CFG] = { 0x09020000, 0x0000000a },
> @@ -256,10 +265,13 @@ static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
> * they are edge-triggered.
> */
> ARMCPU *armcpu;
> + uint32_t max;
> uint32_t irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
>
> + /* 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,
> - GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << vbi->smp_cpus) - 1);
> + GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << max) - 1);
>
> qemu_fdt_add_subnode(vbi->fdt, "/timer");
>
> @@ -283,6 +295,18 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
> {
> int cpu;
>
> + /*
> + * From Documentation/devicetree/bindings/arm/cpus.txt
> + * On ARM v8 64-bit systems value should be set to 2,
> + * that corresponds to the MPIDR_EL1 register size.
> + * If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
> + * in the system, #address-cells can be set to 1, since
> + * MPIDR_EL1[63:32] bits are not used for CPUs
> + * identification.
> + *
> + * Now GIC500 doesn't support affinities 2 & 3 so currently
> + * #address-cells can stay 1 until future GIC
> + */
> qemu_fdt_add_subnode(vbi->fdt, "/cpus");
> qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#address-cells", 0x1);
> qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
> @@ -319,25 +343,36 @@ static void fdt_add_v2m_gic_node(VirtBoardInfo *vbi)
> qemu_fdt_setprop_cell(vbi->fdt, "/intc/v2m", "phandle", vbi->v2m_phandle);
> }
>
> -static void fdt_add_gic_node(VirtBoardInfo *vbi)
> +static void fdt_add_gic_node(VirtBoardInfo *vbi, int type)
> {
> vbi->gic_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
> qemu_fdt_setprop_cell(vbi->fdt, "/", "interrupt-parent", vbi->gic_phandle);
>
> qemu_fdt_add_subnode(vbi->fdt, "/intc");
> - /* 'cortex-a15-gic' means 'GIC v2' */
> - qemu_fdt_setprop_string(vbi->fdt, "/intc", "compatible",
> - "arm,cortex-a15-gic");
> qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#interrupt-cells", 3);
> qemu_fdt_setprop(vbi->fdt, "/intc", "interrupt-controller", NULL, 0);
> - qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc", "reg",
> - 2, vbi->memmap[VIRT_GIC_DIST].base,
> - 2, vbi->memmap[VIRT_GIC_DIST].size,
> - 2, vbi->memmap[VIRT_GIC_CPU].base,
> - 2, vbi->memmap[VIRT_GIC_CPU].size);
> qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#address-cells", 0x2);
> qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#size-cells", 0x2);
> qemu_fdt_setprop(vbi->fdt, "/intc", "ranges", NULL, 0);
> + if (type == KVM_DEV_TYPE_ARM_VGIC_V3) {
> + qemu_fdt_setprop_string(vbi->fdt, "/intc", "compatible",
> + "arm,gic-v3");
> + qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc", "reg",
> + 2, vbi->memmap[VIRT_GIC_DIST].base,
> + 2, vbi->memmap[VIRT_GIC_DIST].size,
> + 2, vbi->memmap[VIRT_LPI].base,
> + 2, vbi->memmap[VIRT_LPI].size);
> + } else {
> + /* 'cortex-a15-gic' means 'GIC v2' */
> + qemu_fdt_setprop_string(vbi->fdt, "/intc", "compatible",
> + "arm,cortex-a15-gic");
> + qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc", "reg",
> + 2, vbi->memmap[VIRT_GIC_DIST].base,
> + 2, vbi->memmap[VIRT_GIC_DIST].size,
> + 2, vbi->memmap[VIRT_GIC_CPU].base,
> + 2, vbi->memmap[VIRT_GIC_CPU].size);
> + }
> +
> qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", vbi->gic_phandle);
> }
>
> @@ -360,20 +395,35 @@ static void create_v2m(VirtBoardInfo *vbi, qemu_irq *pic)
> fdt_add_v2m_gic_node(vbi);
> }
>
> -static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic)
> +static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type)
> {
> /* We create a standalone GIC v2 */
> DeviceState *gicdev;
> SysBusDevice *gicbusdev;
> - const char *gictype = "arm_gic";
> + const char *gictype;
> int i;
>
> - if (kvm_irqchip_in_kernel()) {
> - gictype = "kvm-arm-gic";
> + if (type == KVM_DEV_TYPE_ARM_VGIC_V3) {
> + /* TODO: Software emulation is not implemented yet */
> + if (!kvm_irqchip_in_kernel()) {
> + fprintf(stderr, "KVM is currently required for GICv3 emulation\n");
> + exit(1);
> + }
> + gictype = "kvm-arm-gicv3";
> + } else {
> + gictype = kvm_irqchip_in_kernel() ? "kvm-arm-gic" : "arm_gic";
> }
>
> gicdev = qdev_create(NULL, gictype);
> - qdev_prop_set_uint32(gicdev, "revision", 2);
> +
> + for (i = 0; i < vbi->smp_cpus; i++) {
> + CPUState *cpu = qemu_get_cpu(i);
> + CPUARMState *env = cpu->env_ptr;
> + env->nvic = gicdev;
> + }
> +
> + qdev_prop_set_uint32(gicdev, "revision",
> + type == KVM_DEV_TYPE_ARM_VGIC_V3 ? 3 : 2);
> qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
> /* Note that the num-irq property counts both internal and external
> * interrupts; there are always 32 of the former (mandated by GIC spec).
> @@ -382,7 +432,11 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic)
> qdev_init_nofail(gicdev);
> gicbusdev = SYS_BUS_DEVICE(gicdev);
> sysbus_mmio_map(gicbusdev, 0, vbi->memmap[VIRT_GIC_DIST].base);
> - sysbus_mmio_map(gicbusdev, 1, vbi->memmap[VIRT_GIC_CPU].base);
> + if (type == KVM_DEV_TYPE_ARM_VGIC_V3) {
> + sysbus_mmio_map(gicbusdev, 1, vbi->memmap[VIRT_LPI].base);
> + } else {
> + sysbus_mmio_map(gicbusdev, 1, vbi->memmap[VIRT_GIC_CPU].base);
> + }
>
> /* Wire the outputs from each CPU's generic timer to the
> * appropriate GIC PPI inputs, and the GIC's IRQ output to
> @@ -409,9 +463,11 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic)
> pic[i] = qdev_get_gpio_in(gicdev, i);
> }
>
> - fdt_add_gic_node(vbi);
> + fdt_add_gic_node(vbi, type);
>
> - create_v2m(vbi, pic);
> + if (type == KVM_DEV_TYPE_ARM_VGIC_V2) {
> + create_v2m(vbi, pic);
> + }
> }
As we do not have yet support for ITS implementation in QEMU the device
tree for a GICv3 guest will have a msi-parent property in the device
tree which will point to nothing:
"msi-parent = <0x0>"
Diana
prev parent reply other threads:[~2015-07-15 14:59 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-14 7:54 [Qemu-devel] [PATCH v4 0/5] vGICv3 support Pavel Fedin
2015-07-14 7:54 ` [Qemu-devel] [PATCH v4 1/5] Implement GIC-500 base class Pavel Fedin
2015-07-14 7:54 ` [Qemu-devel] [PATCH v4 2/5] Extract some reusable vGIC code Pavel Fedin
2015-07-14 7:54 ` [Qemu-devel] [PATCH v4 3/5] Introduce irqchip type specification for KVM Pavel Fedin
2015-07-14 7:54 ` [Qemu-devel] [PATCH v4 4/5] Initial implementation of vGICv3 Pavel Fedin
2015-07-15 14:38 ` Diana Craciun
2015-07-15 15:32 ` Pavel Fedin
2015-07-14 7:54 ` [Qemu-devel] [PATCH v4 5/5] Add gicversion option to virt machine Pavel Fedin
2015-07-15 14:44 ` Diana Craciun [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55A671B7.2010808@freescale.com \
--to=diana.craciun@freescale.com \
--cc=christoffer.dall@linaro.org \
--cc=eric.auger@linaro.org \
--cc=p.fedin@samsung.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=shlomo.pongratz@huawei.com \
--cc=shlomopongratz@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.