qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/5] irq: introduce route method in IRQState to get


From: Liu Ping Fan
Subject: [Qemu-devel] [PATCH 1/5] irq: introduce route method in IRQState to get gsi
Date: Thu, 12 Sep 2013 13:24:49 +0800

Since the interrupt pin's connection does not change, so we can decide
the gsi for the pin.  Introducing "route" method in IRQState to do that,
and the implement of "route" requires the guarantee that it can survive
without BQL.

When delivering irq, this will help us to step around the irq system in
qemu, and forward irq directly to kernel where re-entrance is already
allowed.

Signed-off-by: Liu Ping Fan <address@hidden>
---
 hw/core/irq.c    | 39 +++++++++++++++++++++++++++++++++++++++
 include/hw/irq.h |  5 +++++
 2 files changed, 44 insertions(+)

diff --git a/hw/core/irq.c b/hw/core/irq.c
index 2078542..3f88f57 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -26,6 +26,10 @@
 
 struct IRQState {
     qemu_irq_handler handler;
+    /* the implement requires to guarantee the re-entrance without the
+    * protection of BQL
+    */
+    qemu_irq_route route;
     void *opaque;
     int n;
 };
@@ -38,6 +42,15 @@ void qemu_set_irq(qemu_irq irq, int level)
     irq->handler(irq->opaque, irq->n, level);
 }
 
+/* This func is designed to survive without BQL. */
+int qemu_irq_route_gsi(qemu_irq irq)
+{
+    if (irq->route) {
+        return irq->route(irq->opaque, irq->n);
+    }
+    return -1;
+}
+
 qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
                            void *opaque, int n)
 {
@@ -63,6 +76,32 @@ qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, 
qemu_irq_handler handler,
     return s;
 }
 
+qemu_irq *qemu_extend_irqs_2(qemu_irq *old, int n_old, qemu_irq_handler 
handler,
+                           qemu_irq_route route, void *opaque, int n)
+{
+    qemu_irq *s;
+    struct IRQState *p;
+    int i;
+
+    if (!old) {
+        n_old = 0;
+    }
+    s = old ? g_renew(qemu_irq, old, n + n_old) : g_new(qemu_irq, n);
+    p = old ? g_renew(struct IRQState, s[0], n + n_old) :
+                g_new(struct IRQState, n);
+    for (i = 0; i < n + n_old; i++) {
+        if (i >= n_old) {
+            p->handler = handler;
+            p->route = route;
+            p->opaque = opaque;
+            p->n = i;
+        }
+        s[i] = p;
+        p++;
+    }
+    return s;
+}
+
 qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
 {
     return qemu_extend_irqs(NULL, 0, handler, opaque, n);
diff --git a/include/hw/irq.h b/include/hw/irq.h
index 610e6b7..c10ef25 100644
--- a/include/hw/irq.h
+++ b/include/hw/irq.h
@@ -6,6 +6,7 @@
 typedef struct IRQState *qemu_irq;
 
 typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
+typedef int (*qemu_irq_route)(void *opaque, int n);
 
 void qemu_set_irq(qemu_irq irq, int level);
 
@@ -30,11 +31,15 @@ static inline void qemu_irq_pulse(qemu_irq irq)
  */
 qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
 
+int qemu_irq_route_gsi(qemu_irq irq);
+
 /* Extends an Array of IRQs. Old IRQs have their handlers and opaque data
  * preserved. New IRQs are assigned the argument handler and opaque data.
  */
 qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
                                 void *opaque, int n);
+qemu_irq *qemu_extend_irqs_2(qemu_irq *old, int n_old, qemu_irq_handler 
handler,
+                           qemu_irq_route route, void *opaque, int n);
 
 void qemu_free_irqs(qemu_irq *s);
 
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]