#include <xen/early_printk.h>
#include <xen/warning.h>
+#ifdef CONFIG_X86
+#include <asm/guest.h>
+#endif
+
/* console: comma-separated list of console outputs. */
static char __initdata opt_console[30] = OPT_CONSOLE_STR;
string_param("console", opt_console);
static int __read_mostly sercon_handle = -1;
+#ifdef CONFIG_X86
+static bool __read_mostly opt_console_xen; /* console=xen */
+#endif
+
static DEFINE_SPINLOCK(console_lock);
/*
static DECLARE_SOFTIRQ_TASKLET(notify_dom0_con_ring_tasklet,
notify_dom0_con_ring, 0);
+#ifdef CONFIG_X86
+static inline void xen_console_write_debug_port(const char *buf, size_t len)
+{
+ unsigned long tmp;
+ asm volatile ( "rep outsb;"
+ : "=&S" (tmp), "=&c" (tmp)
+ : "0" (buf), "1" (len), "d" (0xe9) );
+}
+#endif
+
static long guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer, int count)
{
char kbuf[128];
sercon_puts(kbuf);
video_puts(kbuf);
+#ifdef CONFIG_X86
+ if ( opt_console_xen )
+ {
+ size_t len = strlen(kbuf);
+
+ if ( xen_guest )
+ xen_hypercall_console_write(kbuf, len);
+ else
+ xen_console_write_debug_port(kbuf, len);
+ }
+#endif
+
if ( opt_console_to_ring )
{
conring_puts(kbuf);
sercon_puts(str);
video_puts(str);
+#ifdef CONFIG_X86
+ if ( opt_console_xen )
+ {
+ size_t len = strlen(str);
+
+ if ( xen_guest )
+ xen_hypercall_console_write(str, len);
+ else
+ xen_console_write_debug_port(str, len);
+ }
+#endif
+
conring_puts(str);
if ( !console_locks_busted )
p++;
if ( !strncmp(p, "vga", 3) )
video_init();
+#ifdef CONFIG_X86
+ else if ( !strncmp(p, "xen", 3) )
+ opt_console_xen = true;
+#endif
else if ( !strncmp(p, "none", 4) )
continue;
else if ( (sh = serial_parse_handle(p)) >= 0 )
/*
* Higher level hypercall helpers
*/
+static inline void xen_hypercall_console_write(
+ const char *buf, unsigned int count)
+{
+ (void)_hypercall64_3(long, __HYPERVISOR_console_io,
+ CONSOLEIO_write, count, buf);
+}
+
static inline long xen_hypercall_shutdown(unsigned int reason)
{
struct sched_shutdown s = { .reason = reason };
#include <public/sched.h>
+static inline void xen_hypercall_console_write(
+ const char *buf, unsigned int count)
+{
+ ASSERT_UNREACHABLE();
+}
+
static inline long xen_hypercall_shutdown(unsigned int reason)
{
ASSERT_UNREACHABLE();