Message ID | 1464274540-19693-10-git-send-email-peter.maydell@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 2016/5/26 22:55, Peter Maydell wrote: > From: Shlomo Pongratz <shlomo.pongratz@huawei.com> > > This patch includes the device class itself, some ID register > value functions which will be needed by both distributor > and redistributor, and some skeleton functions for handling > interrupts coming in and going out, which will be filled in > in a subsequent patch. > > Signed-off-by: Shlomo Pongratz <shlomo.pongratz@huawei.com> > [PMM: pulled this patch earlier in the sequence, and left > some code out of it for a later patch] > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org> > --- > hw/intc/Makefile.objs | 1 + > hw/intc/arm_gicv3.c | 74 +++++++++++++++++++++++++++++++++++++++++++++ > hw/intc/gicv3_internal.h | 24 +++++++++++++++ > include/hw/intc/arm_gicv3.h | 32 ++++++++++++++++++++ > 4 files changed, 131 insertions(+) > create mode 100644 hw/intc/arm_gicv3.c > create mode 100644 include/hw/intc/arm_gicv3.h > > diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs > index 0e47f0f..4e94fdd 100644 > --- a/hw/intc/Makefile.objs > +++ b/hw/intc/Makefile.objs > @@ -13,6 +13,7 @@ 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_ARM_GIC) += arm_gicv3.o > common-obj-$(CONFIG_OPENPIC) += openpic.o > > obj-$(CONFIG_APIC) += apic.o apic_common.o > diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c > new file mode 100644 > index 0000000..96e0d2f > --- /dev/null > +++ b/hw/intc/arm_gicv3.c > @@ -0,0 +1,74 @@ > +/* > + * ARM Generic Interrupt Controller v3 > + * > + * Copyright (c) 2015 Huawei. > + * Copyright (c) 2016 Linaro Limited > + * Written by Shlomo Pongratz, Peter Maydell > + * > + * This code is licensed under the GPL, version 2 or (at your option) > + * any later version. > + */ > + > +/* This file contains implementation code for an interrupt controller > + * which implements the GICv3 architecture. Specifically this is where > + * the device class itself and the functions for handling interrupts > + * coming in and going out live. > + */ > + > +#include "qemu/osdep.h" > +#include "qapi/error.h" > +#include "hw/sysbus.h" > +#include "hw/intc/arm_gicv3.h" > +#include "gicv3_internal.h" > + > +/* Process a change in an external IRQ input. */ > +static void gicv3_set_irq(void *opaque, int irq, int level) > +{ > + /* Meaning of the 'irq' parameter: > + * [0..N-1] : external interrupts > + * [N..N+31] : PPI (internal) interrupts for CPU 0 > + * [N+32..N+63] : PPI (internal interrupts for CPU 1 > + * ... > + */ > + /* Do nothing for now */ > +} > + > +static void arm_gic_realize(DeviceState *dev, Error **errp) > +{ > + /* Device instance realize function for the GIC sysbus device */ > + GICv3State *s = ARM_GICV3(dev); > + ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s); > + Error *local_err = NULL; > + > + agc->parent_realize(dev, &local_err); > + if (local_err) { > + error_propagate(errp, local_err); > + return; > + } > + > + gicv3_init_irqs_and_mmio(s, gicv3_set_irq, NULL); > +} > + > +static void arm_gicv3_class_init(ObjectClass *klass, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(klass); > + ARMGICv3Class *agc = ARM_GICV3_CLASS(klass); > + > + agc->parent_realize = dc->realize; > + dc->realize = arm_gic_realize; > +} > + > +static const TypeInfo arm_gicv3_info = { > + .name = TYPE_ARM_GICV3, > + .parent = TYPE_ARM_GICV3_COMMON, > + .instance_size = sizeof(GICv3State), > + .class_init = arm_gicv3_class_init, > + .class_size = sizeof(ARMGICv3Class), > +}; > + > +static void arm_gicv3_register_types(void) > +{ > + type_register_static(&arm_gicv3_info); > +} > + > +type_init(arm_gicv3_register_types) > diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h > index d23524b..97c9d75 100644 > --- a/hw/intc/gicv3_internal.h > +++ b/hw/intc/gicv3_internal.h > @@ -159,6 +159,30 @@ > #define ICC_CTLR_EL3_A3V (1U << 15) > #define ICC_CTLR_EL3_NDS (1U << 17) > > +static inline uint32_t gicv3_iidr(void) > +{ > + /* Return the Implementer Identification Register value > + * for the emulated GICv3, as reported in GICD_IIDR and GICR_IIDR. > + * > + * We claim to be an ARM r0p0 with a zero ProductID. > + * This is the same as an r0p0 GIC-500. > + */ > + return 0x43b; > +} > + > +static inline uint32_t gicv3_idreg(int regoffset) > +{ > + /* Return the value of the CoreSight ID register at the specified > + * offset from the first ID register (as found in the distributor > + * and redistributor register banks). > + * These values indicate an ARM implementation of a GICv3. > + */ > + static const uint8_t gicd_ids[] = { > + 0x44, 0x00, 0x00, 0x00, 0x92, 0xB4, 0x3B, 0x00, 0x0D, 0xF0, 0x05, 0xB1 > + }; > + return gicd_ids[regoffset / 4]; > +} > + > /** > * gicv3_redist_affid: > * > diff --git a/include/hw/intc/arm_gicv3.h b/include/hw/intc/arm_gicv3.h > new file mode 100644 > index 0000000..4a6fd85 > --- /dev/null > +++ b/include/hw/intc/arm_gicv3.h > @@ -0,0 +1,32 @@ > +/* > + * ARM Generic Interrupt Controller v3 > + * > + * Copyright (c) 2015 Huawei. > + * Copyright (c) 2016 Linaro Limited > + * Written by Shlomo Pongratz, Peter Maydell > + * > + * This code is licensed under the GPL, version 2 or (at your option) > + * any later version. > + */ > + > +#ifndef HW_ARM_GICV3_H > +#define HW_ARM_GICV3_H > + > +#include "arm_gicv3_common.h" > + > +#define TYPE_ARM_GICV3 "arm-gicv3" > +#define ARM_GICV3(obj) OBJECT_CHECK(GICv3State, (obj), TYPE_ARM_GICV3) > +#define ARM_GICV3_CLASS(klass) \ > + OBJECT_CLASS_CHECK(ARMGICv3Class, (klass), TYPE_ARM_GICV3) > +#define ARM_GICV3_GET_CLASS(obj) \ > + OBJECT_GET_CLASS(ARMGICv3Class, (obj), TYPE_ARM_GICV3) > + > +typedef struct ARMGICv3Class { > + /*< private >*/ > + ARMGICv3CommonClass parent_class; > + /*< public >*/ > + > + DeviceRealize parent_realize; > +} ARMGICv3Class; > + > +#endif >
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 0e47f0f..4e94fdd 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -13,6 +13,7 @@ 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_ARM_GIC) += arm_gicv3.o common-obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_APIC) += apic.o apic_common.o diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c new file mode 100644 index 0000000..96e0d2f --- /dev/null +++ b/hw/intc/arm_gicv3.c @@ -0,0 +1,74 @@ +/* + * ARM Generic Interrupt Controller v3 + * + * Copyright (c) 2015 Huawei. + * Copyright (c) 2016 Linaro Limited + * Written by Shlomo Pongratz, Peter Maydell + * + * This code is licensed under the GPL, version 2 or (at your option) + * any later version. + */ + +/* This file contains implementation code for an interrupt controller + * which implements the GICv3 architecture. Specifically this is where + * the device class itself and the functions for handling interrupts + * coming in and going out live. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/sysbus.h" +#include "hw/intc/arm_gicv3.h" +#include "gicv3_internal.h" + +/* Process a change in an external IRQ input. */ +static void gicv3_set_irq(void *opaque, int irq, int level) +{ + /* Meaning of the 'irq' parameter: + * [0..N-1] : external interrupts + * [N..N+31] : PPI (internal) interrupts for CPU 0 + * [N+32..N+63] : PPI (internal interrupts for CPU 1 + * ... + */ + /* Do nothing for now */ +} + +static void arm_gic_realize(DeviceState *dev, Error **errp) +{ + /* Device instance realize function for the GIC sysbus device */ + GICv3State *s = ARM_GICV3(dev); + ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s); + Error *local_err = NULL; + + agc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + gicv3_init_irqs_and_mmio(s, gicv3_set_irq, NULL); +} + +static void arm_gicv3_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + ARMGICv3Class *agc = ARM_GICV3_CLASS(klass); + + agc->parent_realize = dc->realize; + dc->realize = arm_gic_realize; +} + +static const TypeInfo arm_gicv3_info = { + .name = TYPE_ARM_GICV3, + .parent = TYPE_ARM_GICV3_COMMON, + .instance_size = sizeof(GICv3State), + .class_init = arm_gicv3_class_init, + .class_size = sizeof(ARMGICv3Class), +}; + +static void arm_gicv3_register_types(void) +{ + type_register_static(&arm_gicv3_info); +} + +type_init(arm_gicv3_register_types) diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h index d23524b..97c9d75 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -159,6 +159,30 @@ #define ICC_CTLR_EL3_A3V (1U << 15) #define ICC_CTLR_EL3_NDS (1U << 17) +static inline uint32_t gicv3_iidr(void) +{ + /* Return the Implementer Identification Register value + * for the emulated GICv3, as reported in GICD_IIDR and GICR_IIDR. + * + * We claim to be an ARM r0p0 with a zero ProductID. + * This is the same as an r0p0 GIC-500. + */ + return 0x43b; +} + +static inline uint32_t gicv3_idreg(int regoffset) +{ + /* Return the value of the CoreSight ID register at the specified + * offset from the first ID register (as found in the distributor + * and redistributor register banks). + * These values indicate an ARM implementation of a GICv3. + */ + static const uint8_t gicd_ids[] = { + 0x44, 0x00, 0x00, 0x00, 0x92, 0xB4, 0x3B, 0x00, 0x0D, 0xF0, 0x05, 0xB1 + }; + return gicd_ids[regoffset / 4]; +} + /** * gicv3_redist_affid: * diff --git a/include/hw/intc/arm_gicv3.h b/include/hw/intc/arm_gicv3.h new file mode 100644 index 0000000..4a6fd85 --- /dev/null +++ b/include/hw/intc/arm_gicv3.h @@ -0,0 +1,32 @@ +/* + * ARM Generic Interrupt Controller v3 + * + * Copyright (c) 2015 Huawei. + * Copyright (c) 2016 Linaro Limited + * Written by Shlomo Pongratz, Peter Maydell + * + * This code is licensed under the GPL, version 2 or (at your option) + * any later version. + */ + +#ifndef HW_ARM_GICV3_H +#define HW_ARM_GICV3_H + +#include "arm_gicv3_common.h" + +#define TYPE_ARM_GICV3 "arm-gicv3" +#define ARM_GICV3(obj) OBJECT_CHECK(GICv3State, (obj), TYPE_ARM_GICV3) +#define ARM_GICV3_CLASS(klass) \ + OBJECT_CLASS_CHECK(ARMGICv3Class, (klass), TYPE_ARM_GICV3) +#define ARM_GICV3_GET_CLASS(obj) \ + OBJECT_GET_CLASS(ARMGICv3Class, (obj), TYPE_ARM_GICV3) + +typedef struct ARMGICv3Class { + /*< private >*/ + ARMGICv3CommonClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; +} ARMGICv3Class; + +#endif