Message ID | a69d314ad3b7f4043523785ae27c2c5d9cae5dbf.1439904588.git.p.fedin@samsung.com |
---|---|
State | New |
Headers | show |
On 08/18/2015 03:33 PM, Pavel Fedin wrote: > From: Shlomo Pongratz <shlomo.pongratz@huawei.com> > > This class is to be used by both software and KVM implementations of GICv3 > > Currently it is mostly a placeholder, but in future it is supposed to hold > qemu's representation of GICv3 state, which is necessary for migration. > > The interface of this class is fully compatible with GICv2 one. This is > done in order to simplify integration with existing code. > > Signed-off-by: Shlomo Pongratz <shlomo.pongratz@huawei.com> > Signed-off-by: Pavel Fedin <p.fedin@samsung.com> > --- > hw/intc/Makefile.objs | 1 + > hw/intc/arm_gicv3_common.c | 140 +++++++++++++++++++++++++++++++++++++ > include/hw/intc/arm_gicv3_common.h | 68 ++++++++++++++++++ > 3 files changed, 209 insertions(+) > create mode 100644 hw/intc/arm_gicv3_common.c > create mode 100644 include/hw/intc/arm_gicv3_common.h > > diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs > index 092d8a8..1317e5a 100644 > --- a/hw/intc/Makefile.objs > +++ b/hw/intc/Makefile.objs > @@ -12,6 +12,7 @@ common-obj-$(CONFIG_IOAPIC) += ioapic_common.o > common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o > common-obj-$(CONFIG_ARM_GIC) += arm_gic.o > common-obj-$(CONFIG_ARM_GIC) += arm_gicv2m.o > +common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_common.o > common-obj-$(CONFIG_OPENPIC) += openpic.o > > obj-$(CONFIG_APIC) += apic.o apic_common.o > diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c > new file mode 100644 > index 0000000..032ece2 > --- /dev/null > +++ b/hw/intc/arm_gicv3_common.c > @@ -0,0 +1,140 @@ > +/* > + * ARM GICv3 support - common bits of emulated and KVM kernel model > + * > + * Copyright (c) 2012 Linaro Limited > + * Copyright (c) 2015 Huawei. > + * Written by Peter Maydell > + * Extended to 64 cores by Shlomo Pongratz > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation, either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include "hw/intc/arm_gicv3_common.h" > + > +static void gicv3_pre_save(void *opaque) > +{ > + GICv3State *s = (GICv3State *)opaque; > + ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s); > + > + if (c->pre_save) { > + c->pre_save(s); > + } > +} > + > +static int gicv3_post_load(void *opaque, int version_id) > +{ > + GICv3State *s = (GICv3State *)opaque; > + ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s); > + > + if (c->post_load) { > + c->post_load(s); > + } > + return 0; > +} > + > +static const VMStateDescription vmstate_gicv3 = { > + .name = "arm_gicv3", > + .unmigratable = 1, > + .pre_save = gicv3_pre_save, > + .post_load = gicv3_post_load, > +}; > + > +void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler, > + const MemoryRegionOps *ops) > +{ > + SysBusDevice *sbd = SYS_BUS_DEVICE(s); > + int i; > + > + /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU. > + * GPIO array layout is thus: > + * [0..N-1] spi > + * [N..N+31] PPIs for CPU 0 > + * [N+32..N+63] PPIs for CPU 1 > + * ... > + */ > + i = s->num_irq - GIC_INTERNAL + GIC_INTERNAL * s->num_cpu; > + qdev_init_gpio_in(DEVICE(s), handler, i); > + > + s->parent_irq = g_malloc(s->num_cpu * sizeof(qemu_irq)); > + s->parent_fiq = g_malloc(s->num_cpu * sizeof(qemu_irq)); > + > + for (i = 0; i < s->num_cpu; i++) { > + sysbus_init_irq(sbd, &s->parent_irq[i]); > + } > + for (i = 0; i < s->num_cpu; i++) { > + sysbus_init_irq(sbd, &s->parent_fiq[i]); > + } > + > + memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s, > + "gicv3_dist", 0x10000); > + memory_region_init_io(&s->iomem_redist, OBJECT(s), ops ? &ops[1] : NULL, s, > + "gicv3_redist", 0x20000 * s->num_cpu); > + > + sysbus_init_mmio(sbd, &s->iomem_dist); > + sysbus_init_mmio(sbd, &s->iomem_redist); > +} > + > +static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) > +{ > + GICv3State *s = ARM_GICV3_COMMON(dev); > + > + /* revision property is actually reserved and currently used only in order > + * to keep the interface compatible with GICv2 code, avoiding extra > + * conditions. However, in future it could be used, for example, if we > + * implement GICv4. > + */ > + if (s->revision != 3) { > + error_setg(errp, "unsupported GIC revision %d", s->revision); > + return; > + } > +} > + > +static void arm_gicv3_common_reset(DeviceState *dev) > +{ > + /* TODO */ > +} > + > +static Property arm_gicv3_common_properties[] = { > + DEFINE_PROP_UINT32("num-cpu", GICv3State, num_cpu, 1), > + DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32), > + DEFINE_PROP_UINT32("revision", GICv3State, revision, 3), > + DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0), > + DEFINE_PROP_END_OF_LIST(), > +}; > + > +static void arm_gicv3_common_class_init(ObjectClass *klass, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(klass); > + > + dc->reset = arm_gicv3_common_reset; > + dc->realize = arm_gicv3_common_realize; > + dc->props = arm_gicv3_common_properties; > + dc->vmsd = &vmstate_gicv3; > +} > + > +static const TypeInfo arm_gicv3_common_type = { > + .name = TYPE_ARM_GICV3_COMMON, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(GICv3State), > + .class_size = sizeof(ARMGICv3CommonClass), > + .class_init = arm_gicv3_common_class_init, > + .abstract = true, > +}; > + > +static void register_types(void) > +{ > + type_register_static(&arm_gicv3_common_type); > +} > + > +type_init(register_types) > diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h > new file mode 100644 > index 0000000..516dc20 > --- /dev/null > +++ b/include/hw/intc/arm_gicv3_common.h > @@ -0,0 +1,68 @@ > +/* > + * ARM GIC support > + * > + * Copyright (c) 2012 Linaro Limited > + * Copyright (c) 2015 Huawei. > + * Written by Peter Maydell > + * Extended to 64 cores by Shlomo Pongratz > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation, either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, see <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef HW_ARM_GICV3_COMMON_H > +#define HW_ARM_GICV3_COMMON_H > + > +#include "hw/sysbus.h" > +#include "hw/intc/arm_gic_common.h" > + > +typedef struct GICv3State { > + /*< private >*/ > + SysBusDevice parent_obj; > + /*< public >*/ > + > + qemu_irq *parent_irq; > + qemu_irq *parent_fiq; > + > + MemoryRegion iomem_dist; /* Distributor */ > + MemoryRegion iomem_redist; /* Redistributor */ redistributors? Besides Reviewed-by: Eric Auger <eric.auger@linaro.org> > + > + uint32_t num_cpu; > + uint32_t num_irq; > + uint32_t revision; > + bool security_extn; > + > + int dev_fd; /* kvm device fd if backed by kvm vgic support */ > +} GICv3State; > + > +#define TYPE_ARM_GICV3_COMMON "arm_gicv3_common" > +#define ARM_GICV3_COMMON(obj) \ > + OBJECT_CHECK(GICv3State, (obj), TYPE_ARM_GICV3_COMMON) > +#define ARM_GICV3_COMMON_CLASS(klass) \ > + OBJECT_CLASS_CHECK(ARMGICv3CommonClass, (klass), TYPE_ARM_GICV3_COMMON) > +#define ARM_GICV3_COMMON_GET_CLASS(obj) \ > + OBJECT_GET_CLASS(ARMGICv3CommonClass, (obj), TYPE_ARM_GICV3_COMMON) > + > +typedef struct ARMGICv3CommonClass { > + /*< private >*/ > + SysBusDeviceClass parent_class; > + /*< public >*/ > + > + void (*pre_save)(GICv3State *s); > + void (*post_load)(GICv3State *s); > +} ARMGICv3CommonClass; > + > +void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler, > + const MemoryRegionOps *ops); > + > +#endif >
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 092d8a8..1317e5a 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -12,6 +12,7 @@ common-obj-$(CONFIG_IOAPIC) += ioapic_common.o common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o common-obj-$(CONFIG_ARM_GIC) += arm_gic.o common-obj-$(CONFIG_ARM_GIC) += arm_gicv2m.o +common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_common.o common-obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_APIC) += apic.o apic_common.o diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c new file mode 100644 index 0000000..032ece2 --- /dev/null +++ b/hw/intc/arm_gicv3_common.c @@ -0,0 +1,140 @@ +/* + * ARM GICv3 support - common bits of emulated and KVM kernel model + * + * Copyright (c) 2012 Linaro Limited + * Copyright (c) 2015 Huawei. + * Written by Peter Maydell + * Extended to 64 cores by Shlomo Pongratz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "hw/intc/arm_gicv3_common.h" + +static void gicv3_pre_save(void *opaque) +{ + GICv3State *s = (GICv3State *)opaque; + ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s); + + if (c->pre_save) { + c->pre_save(s); + } +} + +static int gicv3_post_load(void *opaque, int version_id) +{ + GICv3State *s = (GICv3State *)opaque; + ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s); + + if (c->post_load) { + c->post_load(s); + } + return 0; +} + +static const VMStateDescription vmstate_gicv3 = { + .name = "arm_gicv3", + .unmigratable = 1, + .pre_save = gicv3_pre_save, + .post_load = gicv3_post_load, +}; + +void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler, + const MemoryRegionOps *ops) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(s); + int i; + + /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU. + * GPIO array layout is thus: + * [0..N-1] spi + * [N..N+31] PPIs for CPU 0 + * [N+32..N+63] PPIs for CPU 1 + * ... + */ + i = s->num_irq - GIC_INTERNAL + GIC_INTERNAL * s->num_cpu; + qdev_init_gpio_in(DEVICE(s), handler, i); + + s->parent_irq = g_malloc(s->num_cpu * sizeof(qemu_irq)); + s->parent_fiq = g_malloc(s->num_cpu * sizeof(qemu_irq)); + + for (i = 0; i < s->num_cpu; i++) { + sysbus_init_irq(sbd, &s->parent_irq[i]); + } + for (i = 0; i < s->num_cpu; i++) { + sysbus_init_irq(sbd, &s->parent_fiq[i]); + } + + memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s, + "gicv3_dist", 0x10000); + memory_region_init_io(&s->iomem_redist, OBJECT(s), ops ? &ops[1] : NULL, s, + "gicv3_redist", 0x20000 * s->num_cpu); + + sysbus_init_mmio(sbd, &s->iomem_dist); + sysbus_init_mmio(sbd, &s->iomem_redist); +} + +static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) +{ + GICv3State *s = ARM_GICV3_COMMON(dev); + + /* revision property is actually reserved and currently used only in order + * to keep the interface compatible with GICv2 code, avoiding extra + * conditions. However, in future it could be used, for example, if we + * implement GICv4. + */ + if (s->revision != 3) { + error_setg(errp, "unsupported GIC revision %d", s->revision); + return; + } +} + +static void arm_gicv3_common_reset(DeviceState *dev) +{ + /* TODO */ +} + +static Property arm_gicv3_common_properties[] = { + DEFINE_PROP_UINT32("num-cpu", GICv3State, num_cpu, 1), + DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32), + DEFINE_PROP_UINT32("revision", GICv3State, revision, 3), + DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void arm_gicv3_common_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->reset = arm_gicv3_common_reset; + dc->realize = arm_gicv3_common_realize; + dc->props = arm_gicv3_common_properties; + dc->vmsd = &vmstate_gicv3; +} + +static const TypeInfo arm_gicv3_common_type = { + .name = TYPE_ARM_GICV3_COMMON, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(GICv3State), + .class_size = sizeof(ARMGICv3CommonClass), + .class_init = arm_gicv3_common_class_init, + .abstract = true, +}; + +static void register_types(void) +{ + type_register_static(&arm_gicv3_common_type); +} + +type_init(register_types) diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h new file mode 100644 index 0000000..516dc20 --- /dev/null +++ b/include/hw/intc/arm_gicv3_common.h @@ -0,0 +1,68 @@ +/* + * ARM GIC support + * + * Copyright (c) 2012 Linaro Limited + * Copyright (c) 2015 Huawei. + * Written by Peter Maydell + * Extended to 64 cores by Shlomo Pongratz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_ARM_GICV3_COMMON_H +#define HW_ARM_GICV3_COMMON_H + +#include "hw/sysbus.h" +#include "hw/intc/arm_gic_common.h" + +typedef struct GICv3State { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + qemu_irq *parent_irq; + qemu_irq *parent_fiq; + + MemoryRegion iomem_dist; /* Distributor */ + MemoryRegion iomem_redist; /* Redistributor */ + + uint32_t num_cpu; + uint32_t num_irq; + uint32_t revision; + bool security_extn; + + int dev_fd; /* kvm device fd if backed by kvm vgic support */ +} GICv3State; + +#define TYPE_ARM_GICV3_COMMON "arm_gicv3_common" +#define ARM_GICV3_COMMON(obj) \ + OBJECT_CHECK(GICv3State, (obj), TYPE_ARM_GICV3_COMMON) +#define ARM_GICV3_COMMON_CLASS(klass) \ + OBJECT_CLASS_CHECK(ARMGICv3CommonClass, (klass), TYPE_ARM_GICV3_COMMON) +#define ARM_GICV3_COMMON_GET_CLASS(obj) \ + OBJECT_GET_CLASS(ARMGICv3CommonClass, (obj), TYPE_ARM_GICV3_COMMON) + +typedef struct ARMGICv3CommonClass { + /*< private >*/ + SysBusDeviceClass parent_class; + /*< public >*/ + + void (*pre_save)(GICv3State *s); + void (*post_load)(GICv3State *s); +} ARMGICv3CommonClass; + +void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler, + const MemoryRegionOps *ops); + +#endif