[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs |
Date: |
Sun, 6 Jun 2010 10:10:58 +0200 |
From: Jan Kiszka <address@hidden>
This patch allows to optionally attach a message to an IRQ event. The
message can contain a payload reference and a callback that the IRQ
handler may invoke to report the delivery result. The former can be used
to model message signaling interrupts, the latter to cleanly implement
IRQ de-coalescing logics.
Signed-off-by: Jan Kiszka <address@hidden>
---
hw/irq.c | 37 ++++++++++++++++++++++++++++++++++++-
hw/irq.h | 38 +++++++++++++++++++++++++++++++++++++-
2 files changed, 73 insertions(+), 2 deletions(-)
diff --git a/hw/irq.c b/hw/irq.c
index 24fb09d..db5136b 100644
--- a/hw/irq.c
+++ b/hw/irq.c
@@ -28,12 +28,31 @@ struct IRQState {
qemu_irq_handler handler;
void *opaque;
int n;
+ IRQMsg *msg;
};
-void qemu_set_irq(qemu_irq irq, int level)
+void qemu_set_irq_msg(qemu_irq irq, int level, IRQMsg *msg)
{
if (irq) {
+ irq->msg = msg;
irq->handler(irq, irq->opaque, irq->n, level);
+ irq->msg = NULL;
+ }
+}
+
+void *qemu_irq_get_payload(qemu_irq irq)
+{
+ IRQMsg *msg = irq->msg;
+
+ return msg ? msg->payload : NULL;
+}
+
+void qemu_irq_fire_delivery_cb(qemu_irq irq, int level, int result)
+{
+ IRQMsg *msg = irq->msg;
+
+ if (msg && msg->delivery_cb) {
+ msg->delivery_cb(irq, msg->delivery_opaque, irq->n, level, result);
}
}
@@ -61,11 +80,27 @@ void qemu_free_irqs(qemu_irq *s)
qemu_free(s);
}
+static void qemu_notirq_delivery_cb(qemu_irq irq, void *opaque, int line,
+ int level, int result)
+{
+ qemu_irq orig_irq = opaque;
+
+ qemu_irq_fire_delivery_cb(orig_irq, !level, result);
+}
+
static void qemu_notirq(qemu_irq irq, void *opaque, int line, int level)
{
struct IRQState *inv_irq = opaque;
+ IRQMsg msg;
+ if (irq->msg) {
+ msg.delivery_cb = qemu_notirq_delivery_cb;
+ msg.delivery_opaque = irq;
+ msg.payload = irq->msg->payload;
+ inv_irq->msg = &msg;
+ }
inv_irq->handler(inv_irq, inv_irq->opaque, inv_irq->n, !level);
+ inv_irq->msg = NULL;
}
qemu_irq qemu_irq_invert(qemu_irq irq)
diff --git a/hw/irq.h b/hw/irq.h
index d0f83e3..01f96af 100644
--- a/hw/irq.h
+++ b/hw/irq.h
@@ -3,26 +3,62 @@
/* Generic IRQ/GPIO pin infrastructure. */
+#define QEMU_IRQ_DELIVERED 0
+#define QEMU_IRQ_COALESCED (-1)
+#define QEMU_IRQ_MASKED (-2)
+
+typedef void (*qemu_irq_delivery_cb)(qemu_irq irq, void *opaque, int n,
+ int level, int result);
typedef void (*qemu_irq_handler)(qemu_irq irq, void *opaque, int n, int level);
-void qemu_set_irq(qemu_irq irq, int level);
+typedef struct IRQMsg {
+ qemu_irq_delivery_cb delivery_cb;
+ void *delivery_opaque;
+ void *payload;
+} IRQMsg;
+
+void qemu_set_irq_msg(qemu_irq irq, int level, IRQMsg *msg);
+
+static inline void qemu_set_irq(qemu_irq irq, int level)
+{
+ qemu_set_irq_msg(irq, level, NULL);
+}
static inline void qemu_irq_raise(qemu_irq irq)
{
qemu_set_irq(irq, 1);
}
+static inline void qemu_irq_raise_msg(qemu_irq irq, IRQMsg *msg)
+{
+ qemu_set_irq_msg(irq, 1, msg);
+}
+
static inline void qemu_irq_lower(qemu_irq irq)
{
qemu_set_irq(irq, 0);
}
+static inline void qemu_irq_lower_msg(qemu_irq irq, IRQMsg *msg)
+{
+ qemu_set_irq_msg(irq, 0, msg);
+}
+
static inline void qemu_irq_pulse(qemu_irq irq)
{
qemu_set_irq(irq, 1);
qemu_set_irq(irq, 0);
}
+static inline void qemu_irq_pulse_msg(qemu_irq irq, IRQMsg *msg)
+{
+ qemu_set_irq_msg(irq, 1, msg);
+ qemu_set_irq_msg(irq, 0, msg);
+}
+
+void qemu_irq_fire_delivery_cb(qemu_irq irq, int level, int result);
+void *qemu_irq_get_payload(qemu_irq irq);
+
/* Returns an array of N IRQs. */
qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
void qemu_free_irqs(qemu_irq *s);
--
1.6.0.2
- [Qemu-devel] [PATCH 00/16] HPET cleanups, fixes, enhancements, Jan Kiszka, 2010/06/06
- [Qemu-devel] [PATCH 01/16] hpet: Catch out-of-bounds timer access, Jan Kiszka, 2010/06/06
- [Qemu-devel] [PATCH 04/16] hpet: Move static timer field initialization, Jan Kiszka, 2010/06/06
- [Qemu-devel] [PATCH 05/16] hpet: Convert to qdev, Jan Kiszka, 2010/06/06
- [Qemu-devel] [PATCH 03/16] hpet: Silence warning on write to running main counter, Jan Kiszka, 2010/06/06
- [Qemu-devel] [PATCH 07/16] monitor/QMP: Drop info hpet / query-hpet, Jan Kiszka, 2010/06/06
- [Qemu-devel] [PATCH 02/16] hpet: Coding style cleanups and some refactorings, Jan Kiszka, 2010/06/06
- [Qemu-devel] [PATCH 06/16] hpet: Start/stop timer when HPET_TN_ENABLE is modified, Jan Kiszka, 2010/06/06
- [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs,
Jan Kiszka <=
- Re: [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs, Paul Brook, 2010/06/12
- Re: [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs, Jan Kiszka, 2010/06/12
- Re: [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs, Blue Swirl, 2010/06/12
- Re: [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs, Paul Brook, 2010/06/12
- Re: [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs, Blue Swirl, 2010/06/12
- Re: [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs, Paul Brook, 2010/06/12
- Re: [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs, Blue Swirl, 2010/06/12
- Re: [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs, Paul Brook, 2010/06/12
- Re: [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs, Blue Swirl, 2010/06/12
- Re: [Qemu-devel] [PATCH 09/16] Enable message delivery via IRQs, Blue Swirl, 2010/06/13