From: Sergiy Kibrik <sergiy.kib...@globallogic.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

osv: xen: independent event interrupt bring up

Initialize Xen event interrupt separately from xenbus driver, so that events
can be served before xenbus is up, or even in case when xenbus not being probed
at all or not required, e.g. in case of aarch64 Xen console.

Signed-off-by: Sergiy Kibrik <sergiy.kib...@globallogic.com>
Message-Id: <1490017967-16388-1-git-send-email-sergiy.kib...@globallogic.com>

---
diff --git a/arch/aarch64/xen.cc b/arch/aarch64/xen.cc
--- a/arch/aarch64/xen.cc
+++ b/arch/aarch64/xen.cc
@@ -8,6 +8,9 @@
 #include <osv/types.h>
 #include <osv/xen.hh>
 #include <xen/interface/xen.h>
+#include <bsd/porting/netport.h> /* __dead2 defined here */
+#include <machine/xen/xen-os.h>
+#include <xen/evtchn.h>

 #include "arch-dtb.hh"

@@ -17,6 +20,20 @@ namespace xen {

 shared_info_t dummy_info;
 struct xen_shared_info xen_shared_info __attribute__((aligned(4096)));
+constexpr int events_irq = 31; /*FIXME: get from FDT */
+
+void irq_init()
+{
+    if (!is_xen())
+        return;
+
+    evtchn_init(NULL);
+
+ auto intr = new spi_interrupt(gic::irq_type::IRQ_TYPE_LEVEL, events_irq,
+                                  xen::xen_ack_irq,
+                                  xen::xen_handle_irq);
+    irq_setup(intr);
+}

 }

diff --git a/arch/x64/xen.cc b/arch/x64/xen.cc
--- a/arch/x64/xen.cc
+++ b/arch/x64/xen.cc
@@ -16,6 +16,7 @@
 #include <osv/sched.hh>
 #include <bsd/porting/pcpu.h>
 #include <machine/xen/xen-os.h>
+#include <xen/evtchn.h>

 shared_info_t *HYPERVISOR_shared_info;
 uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32];
@@ -201,6 +202,20 @@ void xen_init(processor::features_type &features, unsigned base) HYPERVISOR_shared_info = reinterpret_cast<shared_info_t *>(&xen_shared_info);
 }

+void irq_init()
+{
+    if (!is_xen())
+        return;
+
+    evtchn_init(NULL);
+
+ /* if vector callback not supported, platform PCI driver will handle that */
+    if (processor::features().xen_vector_callback)
+        xen::xen_set_callback();
+
+    irq_setup(NULL);
+}
+
 extern "C"
 void xen_init(struct start_info* si)
 {
diff --git a/bsd/sys/xen/evtchn.h b/bsd/sys/xen/evtchn.h
--- a/bsd/sys/xen/evtchn.h
+++ b/bsd/sys/xen/evtchn.h
@@ -32,6 +32,8 @@ void unmask_evtchn(int port);

 int evtchn_from_irq(int irq);

+void evtchn_init(void *arg);
+
 #ifdef SMP
 void rebind_evtchn_to_cpu(int port, unsigned int cpu);
 #else
diff --git a/core/xen_intr.cc b/core/xen_intr.cc
--- a/core/xen_intr.cc
+++ b/core/xen_intr.cc
@@ -111,9 +111,11 @@ void xen_irq::_cpu_init(sched::cpu *c)
     (*(_thread.for_cpu(c)))->start();
 }

-xen_irq::xen_irq()
+xen_irq::xen_irq(interrupt *intr)
     : _cpu_notifier([this] { cpu_init(); })
 {
+    if (intr)
+        _intr.reset(intr);
 }

 static xen_irq *xen_irq_handlers;
@@ -129,13 +131,10 @@ bool xen_ack_irq()
     return true;
 }

-static __attribute__((constructor)) void setup_xen_irq()
+void irq_setup(interrupt *intr)
 {
-    if (!is_xen()) {
-        return;
-    }
-
-    xen_irq_handlers = new xen_irq;
+    assert(is_xen());
+    xen_irq_handlers = new xen_irq(intr);
 }
 }

diff --git a/drivers/xenfront-xenbus.cc b/drivers/xenfront-xenbus.cc
--- a/drivers/xenfront-xenbus.cc
+++ b/drivers/xenfront-xenbus.cc
@@ -26,7 +26,6 @@
 int xs_attach(struct device *);

 int xenpci_irq_init(device_t device, struct xenpci_softc *scp);
-void evtchn_init(void *arg);

 int xenbusb_front_probe(device_t dev);
 int xenbusb_front_attach(device_t dev);
@@ -64,13 +63,7 @@ xenbus::xenbus(pci::device& pci_dev)
     _dev.set_bus_master(true);
     _driver_name = std::string("xenfront-xenbus");

-    // From here on, all the OSV details are sorted, and we start the Xen
-    // bringup
-    evtchn_init(NULL);
-
-    if (processor::features().xen_vector_callback) {
-        xen::xen_set_callback();
-    } else {
+    if (!processor::features().xen_vector_callback) {
         _pgsi.reset(xen::xen_set_callback(irqno));
     }

diff --git a/include/osv/xen.hh b/include/osv/xen.hh
--- a/include/osv/xen.hh
+++ b/include/osv/xen.hh
@@ -16,6 +16,7 @@
 #include <xen/interface/version.h>
 #include <xen/interface/hvm/hvm_op.h>
 #include <osv/alternative.hh>
+#include <osv/interrupt.hh>

 extern char hypercall_page[];
 extern uint8_t xen_features[];
@@ -53,7 +54,8 @@ extern struct xen_shared_info xen_shared_info;
 void xen_set_callback();
 void xen_handle_irq();
 bool xen_ack_irq();
-
+void irq_setup(interrupt *intr);
+void irq_init();
 }


diff --git a/include/osv/xen_intr.hh b/include/osv/xen_intr.hh
--- a/include/osv/xen_intr.hh
+++ b/include/osv/xen_intr.hh
@@ -14,7 +14,7 @@ namespace xen {

 class xen_irq {
 public:
-    explicit xen_irq();
+    explicit xen_irq(interrupt *intr);
     void wake() { (*_thread)->wake(); }
     static void register_irq(int vector, driver_intr_t handler, void *arg);
     static void unregister_irq(int vector);
@@ -24,6 +24,8 @@ private:
     sched::cpu::notifier _cpu_notifier;
     void _cpu_init(sched::cpu *c);

+    std::unique_ptr<interrupt> _intr;
+
     static percpu <sched::thread *> _thread;
 };
 }
diff --git a/loader.cc b/loader.cc
--- a/loader.cc
+++ b/loader.cc
@@ -44,6 +44,7 @@
 #include <osv/sampler.hh>
 #include <osv/app.hh>
 #include <osv/firmware.hh>
+#include <osv/xen.hh>
 #include <dirent.h>
 #include <iostream>
 #include <fstream>
@@ -542,6 +543,7 @@ void main_cont(int ac, char** av)

     setenv("OSV_VERSION", osv::version().c_str(), 1);

+    xen::irq_init();
     smp_launch();
     setenv("OSV_CPUS", std::to_string(sched::cpus.size()).c_str(), 1);
     boot_time.event("SMP launched");

--
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to