]> xenbits.xensource.com Git - people/julieng/freebsd.git/commitdiff
xen/console: Add support for HVM and ARM console
authorJulien Grall <julien.grall@citrix.com>
Sat, 19 Sep 2015 17:15:40 +0000 (18:15 +0100)
committerJulien Grall <julien.grall@citrix.com>
Mon, 2 Nov 2015 11:46:55 +0000 (11:46 +0000)
sys/dev/xen/console/xen_console.c

index 94f08b7f02adb62ad8ff41a44b1a78e0fcce1507..863548fc7ceaff01e080ed9873b7c81e7d69622a 100644 (file)
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <xen/hypervisor.h>
 #include <xen/xen_intr.h>
 #include <xen/interface/io/console.h>
+#include <xen/hvm.h>
 
 #include "opt_ddb.h"
 #include "opt_printf.h"
@@ -273,6 +274,14 @@ static const struct xencons_ops xencons_hypervisor_ops = {
 static void
 xencons_early_init_ring(struct xencons_priv *cons)
 {
+       /*
+        * The ring is initialized later for the HVM console as the
+        * pmap code is not yet fully initialized
+        * TODO: See if we can map the ring in another way earlier.
+        */
+       if (!xen_hvm_domain())
+               return;
+
        /* The shared page for PV is already mapped by the boot code */
        cons->intf = (struct xencons_interface *)console_page;
        cons->evtchn = HYPERVISOR_start_info->console.domU.evtchn;
@@ -283,9 +292,22 @@ xencons_init_ring(device_t dev, struct tty *tp, driver_intr_t intr_handler)
 {
        struct xencons_priv *cons;
        int err;
+       xen_pfn_t pfn;
 
        cons = tty_softc(tp);
 
+       /*
+        * The information are already retrieved in
+        * xencons_early_init_ring for PV guest
+        */
+       if (xen_hvm_domain()) {
+               cons->evtchn = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN);
+               pfn = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN);
+               if (!pfn)
+                       return (ENODEV);
+               cons->intf = xen_pmap(pfn << PAGE_SHIFT, PAGE_SIZE);
+       }
+
        if (cons->evtchn == 0)
                return (ENODEV);
 
@@ -328,6 +350,10 @@ xencons_write_ring(struct xencons_priv *cons, const char *buffer,
 
        xencons_lock_assert(cons);
 
+       /* The console page may have not yet been initialized for HVM domain */
+       if (__predict_false(!intf))
+               return -1;
+
        wcons = intf->out_cons;
        wprod = intf->out_prod;
 
@@ -360,6 +386,10 @@ xencons_read_ring(struct xencons_priv *cons, char *buffer, unsigned int size)
 
        xencons_lock_assert(cons);
 
+       /* The console page may have not yet been initialized for HVM domain */
+       if (__predict_false(!intf))
+               return 0;
+
        rcons = intf->in_cons;
        rprod = intf->in_prod;
        rmb();
@@ -589,8 +619,13 @@ static void
 xencons_cnprobe(struct consdev *cp)
 {
 
+#if defined(__arm__) || defined(__aarch64__)
+       if (!xen_domain())
+               return;
+#else
        if (!xen_pv_domain())
                return;
+#endif
 
        cp->cn_pri = CN_REMOTE;
        sprintf(cp->cn_name, "%s0", driver_name);