[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH RFC V5 3/9] hw/intc: arm_gicv3_cpu_interface
From: |
Shlomo Pongratz |
Subject: |
[Qemu-devel] [PATCH RFC V5 3/9] hw/intc: arm_gicv3_cpu_interface |
Date: |
Tue, 20 Oct 2015 20:22:06 +0300 |
From: Shlomo Pongratz <address@hidden>
This patch incudes the GIC functionality that is exposed to the CPU
via system instructions. In GICv2 this functionality was exposed via
memory mapped access.
Signed-off-by: Shlomo Pongratz <address@hidden>
---
hw/intc/Makefile.objs | 1 +
hw/intc/arm_gicv3_cpu_interface.c | 130 ++++++++++++++++++++++++++++++++++++++
hw/intc/arm_gicv3_cpu_interface.h | 21 ++++++
hw/intc/gicv3_internal.h | 6 ++
4 files changed, 158 insertions(+)
create mode 100644 hw/intc/arm_gicv3_cpu_interface.c
create mode 100644 hw/intc/arm_gicv3_cpu_interface.h
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index e8cdd27..fb6494f 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -14,6 +14,7 @@ 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_interrupts.o
+common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpu_interface.o
common-obj-$(CONFIG_OPENPIC) += openpic.o
obj-$(CONFIG_APIC) += apic.o apic_common.o
diff --git a/hw/intc/arm_gicv3_cpu_interface.c
b/hw/intc/arm_gicv3_cpu_interface.c
new file mode 100644
index 0000000..ba5ee38
--- /dev/null
+++ b/hw/intc/arm_gicv3_cpu_interface.c
@@ -0,0 +1,130 @@
+#include "gicv3_internal.h"
+#include "qom/cpu.h"
+#include "arm_gicv3_cpu_interface.h"
+#include "arm_gicv3_interrupts.h"
+
+/* Cuurently no GICv2 backwards compatibility (no memory mapped regs)
+ * Uses system registers mode.
+ */
+const int gicv3_no_gicv2_bc = 1;
+uint32_t gicv3_sre;
+
+void armv8_gicv3_set_sgi(void *opaque, int cpuindex, uint64_t value)
+{
+ GICv3State *s = (GICv3State *) opaque;
+ int irq, i;
+
+ /* Page 2227 ICC_SGI1R_EL1 */
+
+ irq = (value >> 24) & 0xf;
+
+ /* The external routines use the hardware vector numbering, ie. the first
+ * IRQ is #16. The internal GIC routines use #32 as the first IRQ.
+ */
+ if (irq >= 16)
+ irq += 16;
+
+ /* IRM bit */
+ if (value & (1ll << 40)) {
+ /* Send to all the cores exclude self */
+ for (i = 0; i < cpuindex; i++) {
+ set_bit(cpuindex, s->sgi[irq].state[i].pending);
+ }
+ for (i = cpuindex + 1; i < s->num_cpu; i++) {
+ set_bit(cpuindex, s->sgi[irq].state[i].pending);
+ }
+ /* GIC_SET_PENDING(irq, (ALL_CPU_MASK & ~cm)); */
+ bitmap_fill(s->irq_state[irq].pending, s->num_cpu);
+ clear_bit(cpuindex, s->irq_state[irq].pending);
+ DPRINTF("cpu(%d) sends irq(%d) to ALL exclude self\n", cpuindex, irq);
+ } else {
+ /* Find linear of first core in cluster. See page 2227 ICC_SGI1R_EL1
+ * With our GIC-500 implementation we can have 16 clusters of 8 cpu
each
+ */
+ uint64_t target_affinity;
+ uint64_t target_list;
+ target_affinity = (value >> (16 - ARM_AFF1_SHIFT)) & ARM_AFF1_MASK;
+ target_affinity |= (value >> (32 - ARM_AFF2_SHIFT)) & ARM_AFF2_MASK;
+ target_affinity |= (value >> (48 - ARM_AFF3_SHIFT)) & ARM_AFF3_MASK;
+ target_list = value & 0xff;
+
+ for (i = 0; i < s->num_cpu; i++) {
+ uint64_t cpu_aff0 = s->mp_affinity[i] & ARM_AFF0_MASK;
+ uint64_t cpu_aff123 = s->mp_affinity[i] & ~ARM_AFF0_MASK;
+ if (cpu_aff123 == target_affinity &&
+ ((1 << cpu_aff0) & target_list)) {
+ set_bit(cpuindex, s->sgi[irq].state[i].pending);
+ GIC_SET_PENDING(irq, i);
+ }
+ }
+ }
+ gicv3_update(s);
+}
+
+uint64_t armv8_gicv3_acknowledge_irq(void *opaque, int cpuindex,
+ MemTxAttrs attrs)
+{
+ GICv3State *s = (GICv3State *) opaque;
+ return gicv3_acknowledge_irq(s, cpuindex, attrs);
+}
+
+void armv8_gicv3_complete_irq(void *opaque, int cpuindex, int irq,
+ MemTxAttrs attrs)
+{
+ GICv3State *s = (GICv3State *) opaque;
+ irq &= 0xffffff;
+ gicv3_complete_irq(s, cpuindex, irq, attrs);
+}
+
+uint64_t armv8_gicv3_get_priority_mask(void *opaque, int cpuindex)
+{
+ GICv3State *s = (GICv3State *) opaque;
+ return s->priority_mask[cpuindex];
+}
+
+void armv8_gicv3_set_priority_mask(void *opaque, int cpuindex, uint32_t mask)
+{
+ GICv3State *s = (GICv3State *) opaque;
+ s->priority_mask[cpuindex] = mask & 0xff;
+ DPRINTF("%s cpu(%d) priority mask 0x%x\n",
+ __func__, cpuindex, s->priority_mask[cpuindex]);
+ gicv3_update(s);
+}
+
+uint64_t armv8_gicv3_get_sre(void *opaque)
+{
+ /* Uses only system registers, no memory mapped access GICv2 mode */
+ return gicv3_sre;
+}
+
+void armv8_gicv3_set_sre(void *opaque, uint64_t sre)
+{
+ if (!(sre & 1) && gicv3_no_gicv2_bc) {
+ /* Cuurently no GICv2 backwards compatibility (no memory mapped regs)
+ * Uses system registers mode
+ */
+ DPRINTF("Try to use memory mapped interface sre(0x%lx)\n", sre);
+ assert(0);
+ }
+ gicv3_sre = sre;
+}
+
+uint64_t armv8_gicv3_get_igrpen1(void *opaque, int cpuindex)
+{
+ GICv3State *s = (GICv3State *) opaque;
+ return !!(s->cpu_ctlr[cpuindex] & GICC_CTLR_EN_GRP1);
+}
+
+void armv8_gicv3_set_igrpen1(void *opaque, int cpuindex, uint64_t igrpen1)
+{
+ GICv3State *s = (GICv3State *) opaque;
+ if (igrpen1)
+ s->cpu_ctlr[cpuindex] |= GICC_CTLR_EN_GRP1;
+ else
+ s->cpu_ctlr[cpuindex] &= ~GICC_CTLR_EN_GRP1;
+
+ DPRINTF("CPU Interface %d: Group0 Interrupts %sabled, "
+ "Group1 Interrupts %sabled\n", cpuindex,
+ (s->cpu_ctlr[cpuindex] & GICC_CTLR_EN_GRP0) ? "En" : "Dis",
+ (s->cpu_ctlr[cpuindex] & GICC_CTLR_EN_GRP1) ? "En" : "Dis");
+}
diff --git a/hw/intc/arm_gicv3_cpu_interface.h
b/hw/intc/arm_gicv3_cpu_interface.h
new file mode 100644
index 0000000..fb03c2c
--- /dev/null
+++ b/hw/intc/arm_gicv3_cpu_interface.h
@@ -0,0 +1,21 @@
+#ifndef QEMU_ARM_GICV3_CPU_INTERFACE_H
+#define QEMU_ARM_GICV3_CPU_INTERFACE_H
+
+
+/* These routines are called from cpu64.c and are defined in target-arm/cpu.h
+ * like armv7m_nvic_XXX routines.
+ * I couldn't find how to include it without compilation errors
+ */
+void armv8_gicv3_set_sgi(void *opaque, int cpuindex, uint64_t value);
+uint64_t armv8_gicv3_acknowledge_irq(void *opaque, int cpuindex,
+ MemTxAttrs attrs);
+void armv8_gicv3_complete_irq(void *opaque, int cpuindex, int irq,
+ MemTxAttrs attrs);
+uint64_t armv8_gicv3_get_priority_mask(void *opaque, int cpuindex);
+void armv8_gicv3_set_priority_mask(void *opaque, int cpuindex, uint32_t mask);
+uint64_t armv8_gicv3_get_sre(void *opaque);
+void armv8_gicv3_set_sre(void *opaque, uint64_t sre);
+uint64_t armv8_gicv3_get_igrpen1(void *opaque, int cpuindex);
+void armv8_gicv3_set_igrpen1(void *opaque, int cpuindex, uint64_t igrpen1);
+
+#endif /* !QEMU_ARM_GIC_CPU_INTERFACE_H */
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
index 362455c..14915e0 100644
--- a/hw/intc/gicv3_internal.h
+++ b/hw/intc/gicv3_internal.h
@@ -217,6 +217,12 @@ static inline bool gic_has_groups(GICv3State *s)
return 1;
}
+/* Cuurently no GICv2 backwards compatibility (no memory mapped regs)
+ * Uses system registers mode.
+ */
+extern const int gicv3_no_gicv2_bc;
+extern uint32_t gicv3_sre;
+
#undef DEBUG_GICV3
#ifdef DEBUG_GICV3
--
1.9.1
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, (continued)
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, Shlomo Pongratz, 2015/10/21
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, Pavel Fedin, 2015/10/22
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, Shlomo Pongratz, 2015/10/21
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, Pavel Fedin, 2015/10/21
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, Shlomo Pongratz, 2015/10/21
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, Pavel Fedin, 2015/10/21
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, Shlomo Pongratz, 2015/10/21
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, Pavel Fedin, 2015/10/21
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, Peter Maydell, 2015/10/21
- Re: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its, Pavel Fedin, 2015/10/21
[Qemu-devel] [PATCH RFC V5 3/9] hw/intc: arm_gicv3_cpu_interface,
Shlomo Pongratz <=
[Qemu-devel] [PATCH RFC V5 5/9] hw/intc arm_gicv3_redist, Shlomo Pongratz, 2015/10/20
[Qemu-devel] [PATCH RFC V5 8/9] target-arm/cpu64 GICv3 system instructions support, Shlomo Pongratz, 2015/10/20
- Re: [Qemu-devel] [PATCH RFC V5 8/9] target-arm/cpu64 GICv3 system instructions support, Pavel Fedin, 2015/10/22
- Re: [Qemu-devel] [PATCH RFC V5 8/9] target-arm/cpu64 GICv3 system instructions support, Shlomo Pongratz, 2015/10/22
- Re: [Qemu-devel] [PATCH RFC V5 8/9] target-arm/cpu64 GICv3 system instructions support, Pavel Fedin, 2015/10/22
- Re: [Qemu-devel] [PATCH RFC V5 8/9] target-arm/cpu64 GICv3 system instructions support, Shlomo Pongratz, 2015/10/22
- Re: [Qemu-devel] [PATCH RFC V5 8/9] target-arm/cpu64 GICv3 system instructions support, Pavel Fedin, 2015/10/22
- Re: [Qemu-devel] [PATCH RFC V5 8/9] target-arm/cpu64 GICv3 system instructions support, Shlomo Pongratz, 2015/10/22
[Qemu-devel] [PATCH RFC V5 4/9] hw/intc: arm_gicv3_dist, Shlomo Pongratz, 2015/10/20
[Qemu-devel] [PATCH RFC V5 9/9] hw/arm: Add virt-v3 machine that uses GIC-500, Shlomo Pongratz, 2015/10/20