aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Pau Monné <royger@FreeBSD.org>2014-03-11 10:09:23 +0000
committerRoger Pau Monné <royger@FreeBSD.org>2014-03-11 10:09:23 +0000
commitc203fa69407d940494a0d90988619f900e869989 (patch)
tree030377424ef21e9085fc03f2d6204dd25d2d42a1
parent6f4246bce191e5491dcdaf61df18efa2c9a38a6a (diff)
downloadsrc-c203fa69407d940494a0d90988619f900e869989.tar.gz
src-c203fa69407d940494a0d90988619f900e869989.zip
Notes
-rw-r--r--sys/conf/files4
-rw-r--r--sys/dev/xen/console/console.c85
-rw-r--r--sys/dev/xen/console/xencons_ring.c16
-rw-r--r--sys/i386/include/xen/xen-os.h1
-rw-r--r--sys/i386/xen/xen_machdep.c21
-rw-r--r--sys/x86/xen/pv.c4
-rw-r--r--sys/xen/xen-os.h4
7 files changed, 100 insertions, 35 deletions
diff --git a/sys/conf/files b/sys/conf/files
index c9fb99d5367d..534449827701 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2527,8 +2527,8 @@ dev/xe/if_xe_pccard.c optional xe pccard
dev/xen/balloon/balloon.c optional xen | xenhvm
dev/xen/blkfront/blkfront.c optional xen | xenhvm
dev/xen/blkback/blkback.c optional xen | xenhvm
-dev/xen/console/console.c optional xen
-dev/xen/console/xencons_ring.c optional xen
+dev/xen/console/console.c optional xen | xenhvm
+dev/xen/console/xencons_ring.c optional xen | xenhvm
dev/xen/control/control.c optional xen | xenhvm
dev/xen/netback/netback.c optional xen | xenhvm
dev/xen/netfront/netfront.c optional xen | xenhvm
diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c
index dfabd70c3744..f151ca644774 100644
--- a/sys/dev/xen/console/console.c
+++ b/sys/dev/xen/console/console.c
@@ -27,6 +27,8 @@ __FBSDID("$FreeBSD$");
#include "opt_ddb.h"
+#include "opt_printf.h"
+
#ifdef DDB
#include <ddb/ddb.h>
#endif
@@ -69,11 +71,14 @@ struct mtx cn_mtx;
static char wbuf[WBUF_SIZE];
static char rbuf[RBUF_SIZE];
static int rc, rp;
-static unsigned int cnsl_evt_reg;
+bool cnsl_evt_reg;
static unsigned int wc, wp; /* write_cons, write_prod */
xen_intr_handle_t xen_intr_handle;
device_t xencons_dev;
+/* Virtual address of the shared console page */
+char *console_page;
+
#ifdef KDB
static int xc_altbrk;
#endif
@@ -110,9 +115,70 @@ static struct ttydevsw xc_ttydevsw = {
.tsw_outwakeup = xcoutwakeup,
};
+/*----------------------------- Debug function -------------------------------*/
+struct putchar_arg {
+ char *buf;
+ size_t size;
+ size_t n_next;
+};
+
+static void
+putchar(int c, void *arg)
+{
+ struct putchar_arg *pca;
+
+ pca = (struct putchar_arg *)arg;
+
+ if (pca->buf == NULL) {
+ /*
+ * We have no buffer, output directly to the
+ * console char by char.
+ */
+ HYPERVISOR_console_write((char *)&c, 1);
+ } else {
+ pca->buf[pca->n_next++] = c;
+ if ((pca->size == pca->n_next) || (c = '\0')) {
+ /* Flush the buffer */
+ HYPERVISOR_console_write(pca->buf, pca->n_next);
+ pca->n_next = 0;
+ }
+ }
+}
+
+void
+xc_printf(const char *fmt, ...)
+{
+ va_list ap;
+ struct putchar_arg pca;
+#ifdef PRINTF_BUFR_SIZE
+ char buf[PRINTF_BUFR_SIZE];
+
+ pca.buf = buf;
+ pca.size = sizeof(buf);
+ pca.n_next = 0;
+#else
+ pca.buf = NULL;
+ pca.size = 0;
+#endif
+
+ KASSERT((xen_domain()), ("call to xc_printf from non Xen guest"));
+
+ va_start(ap, fmt);
+ kvprintf(fmt, putchar, &pca, 10, ap);
+ va_end(ap);
+
+#ifdef PRINTF_BUFR_SIZE
+ if (pca.n_next != 0)
+ HYPERVISOR_console_write(buf, pca.n_next);
+#endif
+}
+
static void
xc_cnprobe(struct consdev *cp)
{
+ if (!xen_pv_domain())
+ return;
+
cp->cn_pri = CN_REMOTE;
sprintf(cp->cn_name, "%s0", driver_name);
}
@@ -175,7 +241,7 @@ static void
xc_cnputc(struct consdev *dev, int c)
{
- if (xen_start_info->flags & SIF_INITDOMAIN)
+ if (xen_initial_domain())
xc_cnputc_dom0(dev, c);
else
xc_cnputc_domu(dev, c);
@@ -206,8 +272,7 @@ xcons_putc(int c)
xcons_force_flush();
#endif
}
- if (cnsl_evt_reg)
- __xencons_tx_flush();
+ __xencons_tx_flush();
/* inform start path that we're pretty full */
return ((wp - wc) >= WBUF_SIZE - 100) ? TRUE : FALSE;
@@ -217,6 +282,10 @@ static void
xc_identify(driver_t *driver, device_t parent)
{
device_t child;
+
+ if (!xen_pv_domain())
+ return;
+
child = BUS_ADD_CHILD(parent, 0, driver_name, 0);
device_set_driver(child, driver);
device_set_desc(child, "Xen Console");
@@ -242,10 +311,10 @@ xc_attach(device_t dev)
xencons_ring_init();
- cnsl_evt_reg = 1;
+ cnsl_evt_reg = true;
callout_reset(&xc_callout, XC_POLLTIME, xc_timeout, xccons);
- if (xen_start_info->flags & SIF_INITDOMAIN) {
+ if (xen_initial_domain()) {
error = xen_intr_bind_virq(dev, VIRQ_CONSOLE, 0, NULL,
xencons_priv_interrupt, NULL,
INTR_TYPE_TTY, &xen_intr_handle);
@@ -309,7 +378,7 @@ __xencons_tx_flush(void)
sz = wp - wc;
if (sz > (WBUF_SIZE - WBUF_MASK(wc)))
sz = WBUF_SIZE - WBUF_MASK(wc);
- if (xen_start_info->flags & SIF_INITDOMAIN) {
+ if (xen_initial_domain()) {
HYPERVISOR_console_io(CONSOLEIO_write, sz, &wbuf[WBUF_MASK(wc)]);
wc += sz;
} else {
@@ -426,7 +495,7 @@ xcons_force_flush(void)
{
int sz;
- if (xen_start_info->flags & SIF_INITDOMAIN)
+ if (xen_initial_domain())
return;
/* Spin until console data is flushed through to the domain controller. */
diff --git a/sys/dev/xen/console/xencons_ring.c b/sys/dev/xen/console/xencons_ring.c
index 3701551ea101..42b9abe09947 100644
--- a/sys/dev/xen/console/xencons_ring.c
+++ b/sys/dev/xen/console/xencons_ring.c
@@ -32,9 +32,9 @@ __FBSDID("$FreeBSD$");
#define console_evtchn console.domU.evtchn
xen_intr_handle_t console_handle;
-extern char *console_page;
extern struct mtx cn_mtx;
extern device_t xencons_dev;
+extern bool cnsl_evt_reg;
static inline struct xencons_interface *
xencons_interface(void)
@@ -60,6 +60,9 @@ xencons_ring_send(const char *data, unsigned len)
struct xencons_interface *intf;
XENCONS_RING_IDX cons, prod;
int sent;
+ struct evtchn_send send = {
+ .port = HYPERVISOR_start_info->console_evtchn
+ };
intf = xencons_interface();
cons = intf->out_cons;
@@ -76,7 +79,10 @@ xencons_ring_send(const char *data, unsigned len)
wmb();
intf->out_prod = prod;
- xen_intr_signal(console_handle);
+ if (cnsl_evt_reg)
+ xen_intr_signal(console_handle);
+ else
+ HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
return sent;
@@ -125,11 +131,11 @@ xencons_ring_init(void)
{
int err;
- if (!xen_start_info->console_evtchn)
+ if (HYPERVISOR_start_info->console_evtchn == 0)
return 0;
err = xen_intr_bind_local_port(xencons_dev,
- xen_start_info->console_evtchn, NULL, xencons_handle_input, NULL,
+ HYPERVISOR_start_info->console_evtchn, NULL, xencons_handle_input, NULL,
INTR_TYPE_MISC | INTR_MPSAFE, &console_handle);
if (err) {
return err;
@@ -145,7 +151,7 @@ void
xencons_suspend(void)
{
- if (!xen_start_info->console_evtchn)
+ if (HYPERVISOR_start_info->console_evtchn == 0)
return;
xen_intr_unbind(&console_handle);
diff --git a/sys/i386/include/xen/xen-os.h b/sys/i386/include/xen/xen-os.h
index a8fba61bde7d..3d1ef049cca7 100644
--- a/sys/i386/include/xen/xen-os.h
+++ b/sys/i386/include/xen/xen-os.h
@@ -45,7 +45,6 @@ static inline void rep_nop(void)
#define cpu_relax() rep_nop()
#ifndef XENHVM
-void xc_printf(const char *fmt, ...);
#ifdef SMP
extern int gdtset;
diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c
index fd575ee35053..c1e166b2e7ab 100644
--- a/sys/i386/xen/xen_machdep.c
+++ b/sys/i386/xen/xen_machdep.c
@@ -186,21 +186,6 @@ xen_boothowto(char *envp)
return howto;
}
-#define XC_PRINTF_BUFSIZE 1024
-void
-xc_printf(const char *fmt, ...)
-{
- __va_list ap;
- int retval;
- static char buf[XC_PRINTF_BUFSIZE];
-
- va_start(ap, fmt);
- retval = vsnprintf(buf, XC_PRINTF_BUFSIZE - 1, fmt, ap);
- va_end(ap);
- buf[retval] = 0;
- (void)HYPERVISOR_console_write(buf, retval);
-}
-
#define XPQUEUE_SIZE 128
@@ -745,8 +730,6 @@ void initvalues(start_info_t *startinfo);
struct xenstore_domain_interface;
extern struct xenstore_domain_interface *xen_store;
-char *console_page;
-
void *
bootmem_alloc(unsigned int size)
{
@@ -969,7 +952,7 @@ initvalues(start_info_t *startinfo)
xc_printf("initvalues(): wooh - availmem=%x,%x\n", avail_space,
cur_space);
- xc_printf("KERNBASE=%x,pt_base=%x, VTOPFN(base)=%x, nr_pt_frames=%x\n",
+ xc_printf("KERNBASE=%x,pt_base=%lx, VTOPFN(base)=%x, nr_pt_frames=%lx\n",
KERNBASE,xen_start_info->pt_base, VTOPFN(xen_start_info->pt_base),
xen_start_info->nr_pt_frames);
xendebug_flags = 0; /* 0xffffffff; */
@@ -978,7 +961,7 @@ initvalues(start_info_t *startinfo)
shift_phys_machine(xen_phys_machine, xen_start_info->nr_pages);
#endif
XENPRINTF("IdlePTD %p\n", IdlePTD);
- XENPRINTF("nr_pages: %ld shared_info: 0x%lx flags: 0x%lx pt_base: 0x%lx "
+ XENPRINTF("nr_pages: %ld shared_info: 0x%lx flags: 0x%x pt_base: 0x%lx "
"mod_start: 0x%lx mod_len: 0x%lx\n",
xen_start_info->nr_pages, xen_start_info->shared_info,
xen_start_info->flags, xen_start_info->pt_base,
diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c
index 6805baa2565f..0124d9beacc5 100644
--- a/sys/x86/xen/pv.c
+++ b/sys/x86/xen/pv.c
@@ -73,9 +73,12 @@ hammer_time_xen(start_info_t *si, uint64_t xenstack)
vm_guest = VM_GUEST_XEN;
if ((si == NULL) || (xenstack == 0)) {
+ xc_printf("ERROR: invalid start_info or xen stack, halting\n");
HYPERVISOR_shutdown(SHUTDOWN_crash);
}
+ xc_printf("FreeBSD PVH running on %s\n", si->magic);
+
/* We use 3 pages of xen stack for the boot pagetables */
physfree = xenstack + 3 * PAGE_SIZE - KERNBASE;
@@ -93,6 +96,7 @@ hammer_time_xen(start_info_t *si, uint64_t xenstack)
*/
xen_store = (struct xenstore_domain_interface *)
(ptoa(si->store_mfn) + KERNBASE);
+ console_page = (char *)(ptoa(si->console.domU.mfn) + KERNBASE);
/*
* Use the stack Xen gives us to build the page tables
diff --git a/sys/xen/xen-os.h b/sys/xen/xen-os.h
index 62b5bf65c760..7dd9c7e44c38 100644
--- a/sys/xen/xen-os.h
+++ b/sys/xen/xen-os.h
@@ -55,6 +55,7 @@ extern start_info_t *HYPERVISOR_start_info;
/* XXX: we need to get rid of this and use HYPERVISOR_start_info directly */
extern struct xenstore_domain_interface *xen_store;
+extern char *console_page;
enum xen_domain_type {
XEN_NATIVE, /* running on bare hardware */
@@ -89,6 +90,9 @@ xen_initial_domain(void)
(HYPERVISOR_start_info->flags & SIF_INITDOMAIN) != 0);
}
+/* Debug/emergency function, prints directly to hypervisor console */
+void xc_printf(const char *, ...) __printflike(1, 2);
+
#ifndef xen_mb
#define xen_mb() mb()
#endif