#include <xen/hypercall.h> /* for do_console_io */
#include <xen/early_printk.h>
#include <xen/warning.h>
+#include <asm/guest.h>
/* console: comma-separated list of console outputs. */
static char __initdata opt_console[30] = OPT_CONSOLE_STR;
static int __read_mostly sercon_handle = -1;
+static bool __read_mostly opt_console_xen; /* console=xen */
+
static DEFINE_SPINLOCK(console_lock);
/*
sercon_puts(kbuf);
video_puts(kbuf);
+ if ( opt_console_xen )
+ {
+ unsigned long tmp;
+ size_t len = strlen(kbuf);
+
+ if ( xen_guest )
+ xen_hypercall_console_write(kbuf, len);
+ else
+ asm volatile ( "rep outsb;"
+ : "=&S" (tmp), "=&c" (tmp)
+ : "0" (kbuf), "1" (len), "d" (0xe9) );
+ }
+
if ( opt_console_to_ring )
{
conring_puts(kbuf);
sercon_puts(str);
video_puts(str);
+ if ( opt_console_xen )
+ {
+ unsigned long tmp;
+ size_t len = strlen(str);
+
+ if ( xen_guest )
+ xen_hypercall_console_write(str, len);
+ else
+ asm volatile ( "rep outsb;"
+ : "=&S" (tmp), "=&c" (tmp)
+ : "0" (str), "1" (len), "d" (0xe9) );
+ }
+
conring_puts(str);
if ( !console_locks_busted )
p++;
if ( !strncmp(p, "vga", 3) )
video_init();
+ else if ( !strncmp(p, "xen", 3) )
+ opt_console_xen = true;
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)
{
return xen_hypercall_sched_op(SCHEDOP_shutdown, &reason);
#else /* CONFIG_XEN_GUEST */
+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();