[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [PATCH v2 14/22] hw/intc/arm_gicv3: Implement gicv3_set_irq()
From: |
Peter Maydell |
Subject: |
[Qemu-arm] [PATCH v2 14/22] hw/intc/arm_gicv3: Implement gicv3_set_irq() |
Date: |
Thu, 26 May 2016 15:55:32 +0100 |
Implement the code which updates the GIC state when an interrupt
input into the GIC is asserted.
Signed-off-by: Peter Maydell <address@hidden>
---
hw/intc/arm_gicv3.c | 20 +++++++++++++++++++-
hw/intc/arm_gicv3_dist.c | 21 +++++++++++++++++++++
hw/intc/arm_gicv3_redist.c | 21 +++++++++++++++++++++
hw/intc/gicv3_internal.h | 2 ++
trace-events | 2 ++
5 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
index e8f6766..e770409 100644
--- a/hw/intc/arm_gicv3.c
+++ b/hw/intc/arm_gicv3.c
@@ -311,7 +311,25 @@ static void gicv3_set_irq(void *opaque, int irq, int level)
* [N+32..N+63] : PPI (internal interrupts for CPU 1
* ...
*/
- /* Do nothing for now */
+ GICv3State *s = opaque;
+
+ if (irq < (s->num_irq - GIC_INTERNAL)) {
+ /* external interrupt (SPI) */
+ gicv3_dist_set_irq(s, irq + GIC_INTERNAL, level);
+ } else {
+ /* per-cpu interrupt (PPI) */
+ int cpu;
+
+ irq -= (s->num_irq - GIC_INTERNAL);
+ cpu = irq / GIC_INTERNAL;
+ irq %= GIC_INTERNAL;
+ assert(cpu < s->num_cpu);
+ /* Raising SGIs via this function would be a bug in how the board
+ * model wires up interrupts.
+ */
+ assert(irq >= 16 && irq < 32);
+ gicv3_redist_set_irq(&s->cpu[cpu], irq, level);
+ }
}
static void arm_gicv3_post_load(GICv3State *s)
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
index 6ccb4d9..1634974 100644
--- a/hw/intc/arm_gicv3_dist.c
+++ b/hw/intc/arm_gicv3_dist.c
@@ -850,3 +850,24 @@ MemTxResult gicv3_dist_write(void *opaque, hwaddr offset,
uint64_t data,
}
return r;
}
+
+void gicv3_dist_set_irq(GICv3State *s, int irq, int level)
+{
+ /* Update distributor state for a change in an external SPI input line */
+ if (level == gicv3_gicd_level_test(s, irq)) {
+ return;
+ }
+
+ trace_gicv3_dist_set_irq(irq, level);
+
+ gicv3_gicd_level_replace(s, irq, level);
+
+ if (level) {
+ /* 0->1 edges latch the pending bit for edge-triggered interrupts */
+ if (gicv3_gicd_edge_trigger_test(s, irq)) {
+ gicv3_gicd_pending_set(s, irq);
+ }
+ }
+
+ gicv3_update(s, irq, 1);
+}
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
index 18dc0c8..16b3422 100644
--- a/hw/intc/arm_gicv3_redist.c
+++ b/hw/intc/arm_gicv3_redist.c
@@ -493,3 +493,24 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr
offset, uint64_t data,
}
return r;
}
+
+void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
+{
+ /* Update redistributor state for a change in an external PPI input line */
+ if (level == extract32(cs->level, irq, 1)) {
+ return;
+ }
+
+ trace_gicv3_redist_set_irq(gicv3_redist_affid(cs), irq, level);
+
+ cs->level = deposit32(cs->level, irq, 1, level);
+
+ if (level) {
+ /* 0->1 edges latch the pending bit for edge-triggered interrupts */
+ if (extract32(cs->edge_trigger, irq, 1)) {
+ cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 1);
+ }
+ }
+
+ gicv3_redist_update(cs);
+}
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
index 39196fa..8ae6d66 100644
--- a/hw/intc/gicv3_internal.h
+++ b/hw/intc/gicv3_internal.h
@@ -209,6 +209,8 @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset,
uint64_t *data,
unsigned size, MemTxAttrs attrs);
MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
unsigned size, MemTxAttrs attrs);
+void gicv3_dist_set_irq(GICv3State *s, int irq, int level);
+void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level);
/**
* gicv3_cpuif_update:
diff --git a/trace-events b/trace-events
index 308d458..c006723 100644
--- a/trace-events
+++ b/trace-events
@@ -1922,9 +1922,11 @@ gicv3_dist_read(uint64_t offset, uint64_t data, unsigned
size, bool secure) "GIC
gicv3_dist_badread(uint64_t offset, unsigned size, bool secure) "GICv3
distributor read: offset 0x%" PRIx64 " size %u secure %d: error"
gicv3_dist_write(uint64_t offset, uint64_t data, unsigned size, bool secure)
"GICv3 distributor write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u
secure %d"
gicv3_dist_badwrite(uint64_t offset, uint64_t data, unsigned size, bool
secure) "GICv3 distributor write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size
%u secure %d: error"
+gicv3_dist_set_irq(int irq, int level) "GICv3 distributor interrupt %d level
changed to %d"
# hw/intc/arm_gicv3_redist.c
gicv3_redist_read(uint32_t cpu, uint64_t offset, uint64_t data, unsigned size,
bool secure) "GICv3 redistributor %x read: offset 0x%" PRIx64 " data 0x%"
PRIx64 " size %u secure %d"
gicv3_redist_badread(uint32_t cpu, uint64_t offset, unsigned size, bool
secure) "GICv3 redistributor %x read: offset 0x%" PRIx64 " size %u secure %d:
error"
gicv3_redist_write(uint32_t cpu, uint64_t offset, uint64_t data, unsigned
size, bool secure) "GICv3 redistributor %x write: offset 0x%" PRIx64 " data
0x%" PRIx64 " size %u secure %d"
gicv3_redist_badwrite(uint32_t cpu, uint64_t offset, uint64_t data, unsigned
size, bool secure) "GICv3 redistributor %x write: offset 0x%" PRIx64 " data
0x%" PRIx64 " size %u secure %d: error"
+gicv3_redist_set_irq(uint32_t cpu, int irq, int level) "GICv3 redistributor %x
interrupt %d level changed to %d"
--
1.9.1
- [Qemu-arm] [PATCH v2 00/22] GICv3 emulation, Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 13/22] hw/intc/arm_gicv3: Wire up distributor and redistributor MMIO regions, Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 14/22] hw/intc/arm_gicv3: Implement gicv3_set_irq(),
Peter Maydell <=
- [Qemu-arm] [PATCH v2 11/22] hw/intc/arm_gicv3: Implement GICv3 distributor registers, Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 17/22] hw/intc/arm_gicv3: Implement CPU i/f SGI generation registers, Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 19/22] target-arm/machine.c: Allow user to request GICv3 emulation, Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 16/22] hw/intc/arm_gicv3: Implement gicv3_cpuif_update(), Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 21/22] NOT-FOR-UPSTREAM: kernel: Add definitions for GICv3 attributes, Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 07/22] hw/intc/arm_gicv3: Move irq lines into GICv3CPUState structure, Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 04/22] target-arm: Provide hook to tell GICv3 about changes of security state, Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 02/22] bitops.h: Implement half-shuffle and half-unshuffle ops, Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 08/22] hw/intc/arm_gicv3: Add vmstate descriptors, Peter Maydell, 2016/05/26
- [Qemu-arm] [PATCH v2 01/22] migration: Define VMSTATE_UINT64_2DARRAY, Peter Maydell, 2016/05/26