From: Shlomo Pongratz <shlomo.pongr...@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.pongr...@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.mayd...@linaro.org> Reviewed-by: Shannon Zhao <shannon.z...@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 -- 1.9.1