]> 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>
Sat, 3 Oct 2015 18:37:40 +0000 (19:37 +0100)
sys/dev/xen/console/xen_console.c

index 3c1ed8c0ec1cd476b1fea9d1fef440159c638a8d..fc2aa0424b6492b2b145dda738122f9c4a8a6cc1 100644 (file)
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 
 #include <xen/interface/io/console.h>
+#include <xen/hvm.h>
 
 #include "opt_ddb.h"
 #include "opt_printf.h"
@@ -234,6 +235,14 @@ xencons_read_hypervisor(struct xencons_priv *cons, const char *buffer,
 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;
@@ -244,6 +253,19 @@ xencons_init_ring(device_t dev, struct tty *tp)
 {
        struct xencons_priv *cons = tty_softc(tp);
        int err;
+       xen_pfn_t pfn;
+
+       /*
+        * 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)
                return (ENODEV);
@@ -287,6 +309,10 @@ xencons_write_ring(struct xencons_priv *cons, const char *buffer,
 
        CN_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;
        sent = 0;
@@ -318,6 +344,10 @@ xencons_read_ring(struct xencons_priv *cons, char *buffer, unsigned int size)
 
        CN_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();
@@ -520,8 +550,13 @@ xencons_shutdown(void *arg, int howto)
 static void
 xc_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);