aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorShlomo Pongratz <shlomo.pongratz@huawei.com>2016-06-17 15:23:46 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-06-17 15:23:51 +0100
commit56992670a45aa14637dafc145e9f9b68172efb13 (patch)
tree63cc9a90d56db165ddcfae93a430d2baf0193ab0 /hw/intc
parent757caeed7600028562d5017b93bf2ac2197d0e1c (diff)
downloadqemu-56992670a45aa14637dafc145e9f9b68172efb13.zip
qemu-56992670a45aa14637dafc145e9f9b68172efb13.tar.gz
qemu-56992670a45aa14637dafc145e9f9b68172efb13.tar.bz2
hw/intc/arm_gicv3: ARM GICv3 device framework
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> Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org> Tested-by: Shannon Zhao <shannon.zhao@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1465915112-29272-10-git-send-email-peter.maydell@linaro.org [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>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/Makefile.objs1
-rw-r--r--hw/intc/arm_gicv3.c74
-rw-r--r--hw/intc/gicv3_internal.h24
3 files changed, 99 insertions, 0 deletions
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:
*