]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/xen.git/commitdiff
libxendevicemodel: functions for handling emulated IRQs
authorIan Campbell <ian.campbell@citrix.com>
Fri, 29 Jan 2016 10:16:35 +0000 (10:16 +0000)
committerIan Campbell <ian.campbell@citrix.com>
Wed, 10 Feb 2016 17:09:53 +0000 (17:09 +0000)
Includes injection (set level) and routing of PCI INTx to ISA IRQs.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
tools/libs/devicemodel/Makefile
tools/libs/devicemodel/emuirq.c [new file with mode: 0644]
tools/libs/devicemodel/include/xendevicemodel.h
tools/libs/devicemodel/libxendevicemodel.map

index 07358fc906e242f3b6a311c96812c1b2defed536..86d2b1b821569852d554a85896a11957435edc03 100644 (file)
@@ -14,6 +14,7 @@ LDLIBS   += $(LDLIBS_libxentoollog)
 LDLIBS   += $(LDLIBS_libxencall)
 
 SRCS-y   += core.c
+SRCS-y   += emuirq.c
 
 LIB_OBJS := $(patsubst %.c,%.o,$(SRCS-y))
 PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS-y))
diff --git a/tools/libs/devicemodel/emuirq.c b/tools/libs/devicemodel/emuirq.c
new file mode 100644 (file)
index 0000000..7b5a55d
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "private.h"
+
+int xendevicemodel_set_pci_intx_level(xendevicemodel_handle *dm,
+                                      uint8_t domain, uint8_t bus, uint8_t dev,
+                                      uint8_t intx, bool assert)
+{
+    xen_hvm_set_pci_intx_level_t *arg;
+    int ret = -1;
+
+    arg = xencall_alloc_buffer(dm->call, sizeof(*arg));
+    if ( arg == NULL )
+    {
+        LOGE(ERROR, "unable to allocate memory for set PCI INTx hypercall");
+        goto err;
+    }
+
+    arg->domid  = dm->domid;
+    arg->domain = domain;
+    arg->bus    = bus;
+    arg->device = dev;
+    arg->intx   = intx;
+    arg->level  = assert ? 1 : 0;
+
+    ret = xencall2(dm->call, __HYPERVISOR_hvm_op,
+                   HVMOP_set_pci_intx_level,
+                   (uintptr_t)(arg));
+
+    if ( ret )
+        LOGE(ERROR, "set PCI INTx hypercall failed");
+
+    xencall_free_buffer(dm->call, arg);
+
+ err:
+    return ret;
+}
+
+int xendevicemodel_route_pci_intx_to_isa_irq(xendevicemodel_handle *dm,
+                                             uint8_t intx, uint8_t isa_irq)
+{
+    xen_hvm_set_pci_link_route_t *arg;
+    int ret = -1;
+
+    arg = xencall_alloc_buffer(dm->call, sizeof(*arg));
+    if ( arg == NULL )
+    {
+        LOGE(ERROR,
+             "unable to allocate memory for route PCI INTx to ISA IRQ hypercall");
+        goto err;
+    }
+
+    arg->domid   = dm->domid;
+    arg->link    = intx;
+    arg->isa_irq = isa_irq;
+
+    ret = xencall2(dm->call, __HYPERVISOR_hvm_op,
+                   HVMOP_set_pci_link_route,
+                   (uintptr_t)arg);
+
+    if ( ret )
+        LOGE(ERROR, "route PCI INTx to ISA IRQ hypercall failed");
+
+    xencall_free_buffer(dm->call, arg);
+
+ err:
+    return ret;
+}
+
+int xendevicemodel_set_isa_irq_level(xendevicemodel_handle *dm,
+                                     uint8_t isa_irq, bool assert)
+{
+    xen_hvm_set_isa_irq_level_t *arg;
+    int ret = -1;
+
+    arg = xencall_alloc_buffer(dm->call, sizeof(*arg));
+    if ( arg == NULL )
+    {
+        LOGE(ERROR, "unable to allocate memory for set ISA IRQ level hypercall");
+        goto err;
+    }
+
+    arg->domid   = dm->domid;
+    arg->isa_irq = isa_irq;
+    arg->level   = assert ? 1 : 0;
+
+    ret = xencall2(dm->call, __HYPERVISOR_hvm_op,
+                   HVMOP_set_isa_irq_level,
+                   (uintptr_t)arg);
+
+    if ( ret )
+        LOGE(ERROR, "set ISA IRQ level hypercall failed");
+
+    xencall_free_buffer(dm->call, arg);
+
+ err:
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
index f859e023cbed33a369969024b8d11123d84f6002..991ea6327954166902875d62c9e39fd11e18cb9d 100644 (file)
@@ -104,6 +104,7 @@ int xendevicemodel_close(xendevicemodel_handle *dm);
 
 /*
  * Indicate domain lifecycle changes to the hypervisor.
+ * ====================================================
  *
  * shutdown, reboot and s3_suspend indicate to the hypervisor that
  * emulation has resulted in the given guest behaviour.
@@ -117,6 +118,25 @@ int xendevicemodel_reboot(xendevicemodel_handle *dm);
 int xendevicemodel_s3_suspend(xendevicemodel_handle *dm);
 int xendevicemodel_s3_awaken(xendevicemodel_handle *dm);
 
+/*
+ * Emulated interrupt control and injection.
+ * =========================================
+ *
+ * For PCI INTX and ISA IRQ related functions:
+ *
+ * @intx        PCI INTA (=0) thru INTD (=3).
+ * @isa_irq     ISA IRQ 0..15 (inclusive).
+ * @assert      Whether the given interrupt of the given type should be
+ *              asserted or deasserted.
+ */
+int xendevicemodel_set_pci_intx_level(xendevicemodel_handle *dm,
+                                      uint8_t domain, uint8_t bus, uint8_t dev,
+                                      uint8_t intx, bool assert);
+int xendevicemodel_route_pci_intx_to_isa_irq(xendevicemodel_handle *dm,
+                                             uint8_t intx, uint8_t isa_irq);
+int xendevicemodel_set_isa_irq_level(xendevicemodel_handle *dm,
+                                     uint8_t isa_irq, bool assert);
+
 #endif
 /*
  * Local variables:
index 1c3d93a3722d3689e30dcda3e314b96701e740a9..085a189bcabccf4a330ac2730a4625f3cd4e1b09 100644 (file)
@@ -8,5 +8,9 @@ VERS_1.0 {
                xendevicemodel_s3_suspend;
                xendevicemodel_s3_awaken;
 
+               xendevicemodel_set_pci_intx_level;
+               xendevicemodel_route_pci_intx_to_isa_irq;
+               xendevicemodel_set_isa_irq_level;
+
        local: *; /* Do not expose anything by default */
 };