From: Nadav Har'El <n...@scylladb.com>
Committer: GitHub <nore...@github.com>
Branch: master
Merge pull request #842 from sa-kib/aarch64-xen-v2
[RFC][V2] aarch64: basic Xen support
Reviewed-by: Nadav Har'El <n...@scylladb.com>
---
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -338,7 +338,7 @@ CFLAGS = -std=gnu99 $(COMMON)
CFLAGS += -I libc/stdio -I libc/internal -I libc/arch/$(arch) \
-Wno-missing-braces -Wno-parentheses -Wno-unused-but-set-variable
-ASFLAGS = -g $(autodepend) -DASSEMBLY
+ASFLAGS = -g $(autodepend) -D__ASSEMBLY__
$(out)/fs/vfs/main.o: CXXFLAGS += -Wno-sign-compare -Wno-write-strings
@@ -822,6 +822,7 @@ endif # x64
ifeq ($(arch),aarch64)
drivers += drivers/pl011.o
+drivers += drivers/xenconsole.o
drivers += drivers/virtio.o
drivers += drivers/virtio-vring.o
drivers += drivers/virtio-rng.o
@@ -850,6 +851,7 @@ objects += arch/$(arch)/pci.o
objects += arch/$(arch)/msi.o
objects += arch/$(arch)/power.o
objects += arch/$(arch)/feexcept.o
+objects += arch/$(arch)/xen.o
$(out)/arch/x64/string-ssse3.o: CXXFLAGS += -mssse3
@@ -858,6 +860,7 @@ objects += arch/$(arch)/psci.o
objects += arch/$(arch)/arm-clock.o
objects += arch/$(arch)/gic.o
objects += arch/$(arch)/arch-dtb.o
+objects += arch/$(arch)/hypercall.o
objects += $(libfdt)
endif
@@ -869,7 +872,6 @@ objects += arch/x64/ioapic.o
objects += arch/x64/apic.o
objects += arch/x64/apic-clock.o
objects += arch/x64/entry-xen.o
-objects += arch/x64/xen.o
objects += arch/x64/xen_intr.o
objects += core/sampler.o
objects += $(acpi)
diff --git a/arch/aarch64/arch-dtb.cc b/arch/aarch64/arch-dtb.cc
--- a/arch/aarch64/arch-dtb.cc
+++ b/arch/aarch64/arch-dtb.cc
@@ -362,7 +362,6 @@ static int dtb_get_pci_node()
goto out;
}
- abort("dtb_get_pci_node: no CAM or ECAM node found.\n");
out:
return dtb_pci_node;
}
@@ -570,3 +569,11 @@ bool dtb_get_pci_irqmap(u32 *bdfs, int *irq_ids, int n)
}
return true;
}
+
+bool dtb_get_vmm_is_xen()
+{
+ if (fdt_check_header(dtb) != 0)
+ return false; /* broken header will be handled later */
+
+ return fdt_node_offset_by_compatible(dtb, -1, "xen,xen") >= 0;
+}
diff --git a/arch/aarch64/arch-dtb.hh b/arch/aarch64/arch-dtb.hh
--- a/arch/aarch64/arch-dtb.hh
+++ b/arch/aarch64/arch-dtb.hh
@@ -131,4 +131,11 @@ bool dtb_get_pci_irqmap(u32 *bdfs, int *irq_ids, int
n);
#define DTB_PHYSHI_D_SH 11
#define DTB_PHYSHI_F_SH 8
+/* bool dtb_get_vmm_is_xen();
+ *
+ * Returns true if Xen hypervisor is detected.
+ */
+
+bool dtb_get_vmm_is_xen();
+
#endif /* ARCH_DTB_HH */
diff --git a/arch/aarch64/arch-mmu.hh b/arch/aarch64/arch-mmu.hh
--- a/arch/aarch64/arch-mmu.hh
+++ b/arch/aarch64/arch-mmu.hh
@@ -19,7 +19,7 @@
namespace mmu {
constexpr int max_phys_addr_size = 48;
// device_range_* are used only for debug purpose
-constexpr int device_range_start = 0x8000000;
+constexpr int device_range_start = 0x3000000;
constexpr int device_range_stop = 0x40000000;
extern u64 mem_addr; /* set by the dtb_setup constructor */
diff --git a/arch/aarch64/arch-setup.cc b/arch/aarch64/arch-setup.cc
--- a/arch/aarch64/arch-setup.cc
+++ b/arch/aarch64/arch-setup.cc
@@ -19,6 +19,7 @@
#include "arch-mmu.hh"
#include "arch-dtb.hh"
+#include "xen.hh"
#include "drivers/console.hh"
#include "drivers/pl011.hh"
@@ -39,6 +40,36 @@ void setup_temporary_phys_map()
mmu::flush_tlb_all();
}
+void arch_setup_pci()
+{
+ pci::set_pci_ecam(dtb_get_pci_is_ecam());
+
+ /* linear_map [TTBR0 - PCI config space] */
+ u64 pci_cfg;
+ size_t pci_cfg_len;
+ if (!dtb_get_pci_cfg(&pci_cfg, &pci_cfg_len))
+ return;
+
+ pci::set_pci_cfg(pci_cfg, pci_cfg_len);
+ pci_cfg = pci::get_pci_cfg(&pci_cfg_len);
+ mmu::linear_map((void *)pci_cfg, (mmu::phys)pci_cfg, pci_cfg_len,
+ mmu::page_size, mmu::mattr::dev);
+
+ /* linear_map [TTBR0 - PCI I/O and memory ranges] */
+ u64 ranges[2]; size_t ranges_len[2];
+ if (!dtb_get_pci_ranges(ranges, ranges_len, 2)) {
+ abort("arch-setup: failed to get PCI ranges.\n");
+ }
+ pci::set_pci_io(ranges[0], ranges_len[0]);
+ pci::set_pci_mem(ranges[1], ranges_len[1]);
+ ranges[0] = pci::get_pci_io(&ranges_len[0]);
+ ranges[1] = pci::get_pci_mem(&ranges_len[1]);
+ mmu::linear_map((void *)ranges[0], (mmu::phys)ranges[0], ranges_len[0],
+ mmu::page_size, mmu::mattr::dev);
+ mmu::linear_map((void *)ranges[1], (mmu::phys)ranges[1], ranges_len[1],
+ mmu::page_size, mmu::mattr::dev);
+}
+
void arch_setup_free_memory()
{
setup_temporary_phys_map();
@@ -60,10 +91,12 @@ void arch_setup_free_memory()
mmu::linear_map((void *)mmu::mem_addr, (mmu::phys)mmu::mem_addr,
addr - mmu::mem_addr);
- /* linear_map [TTBR0 - UART] */
- addr = (mmu::phys)console::arch_early_console.get_base_addr();
- mmu::linear_map((void *)addr, addr, 0x1000, mmu::page_size,
- mmu::mattr::dev);
+ if (!is_xen()) {
+ /* linear_map [TTBR0 - UART] */
+ addr = (mmu::phys)console::aarch64_console.pl011.get_base_addr();
+ mmu::linear_map((void *)addr, addr, 0x1000, mmu::page_size,
+ mmu::mattr::dev);
+ }
/* linear_map [TTBR0 - GIC DIST and GIC CPU] */
u64 dist, cpu;
@@ -77,32 +110,7 @@ void arch_setup_free_memory()
mmu::linear_map((void *)cpu, (mmu::phys)cpu, cpu_len, mmu::page_size,
mmu::mattr::dev);
- pci::set_pci_ecam(dtb_get_pci_is_ecam());
-
- /* linear_map [TTBR0 - PCI config space] */
- u64 pci_cfg;
- size_t pci_cfg_len;
- if (!dtb_get_pci_cfg(&pci_cfg, &pci_cfg_len)) {
- abort("arch-setup: failed to get PCI configuration.\n");
- }
- pci::set_pci_cfg(pci_cfg, pci_cfg_len);
- pci_cfg = pci::get_pci_cfg(&pci_cfg_len);
- mmu::linear_map((void *)pci_cfg, (mmu::phys)pci_cfg, pci_cfg_len,
- mmu::page_size, mmu::mattr::dev);
-
- /* linear_map [TTBR0 - PCI I/O and memory ranges] */
- u64 ranges[2]; size_t ranges_len[2];
- if (!dtb_get_pci_ranges(ranges, ranges_len, 2)) {
- abort("arch-setup: failed to get PCI ranges.\n");
- }
- pci::set_pci_io(ranges[0], ranges_len[0]);
- pci::set_pci_mem(ranges[1], ranges_len[1]);
- ranges[0] = pci::get_pci_io(&ranges_len[0]);
- ranges[1] = pci::get_pci_mem(&ranges_len[1]);
- mmu::linear_map((void *)ranges[0], (mmu::phys)ranges[0], ranges_len[0],
- mmu::page_size, mmu::mattr::dev);
- mmu::linear_map((void *)ranges[1], (mmu::phys)ranges[1], ranges_len[1],
- mmu::page_size, mmu::mattr::dev);
+ arch_setup_pci();
mmu::switch_to_runtime_page_tables();
@@ -152,8 +160,11 @@ void arch_init_drivers()
pci::dump_pci_irqmap();
// Enumerate PCI devices
- pci::pci_device_enumeration();
- boot_time.event("pci enumerated");
+ size_t pci_cfg_len;
+ if (pci::get_pci_cfg(&pci_cfg_len)) {
+ pci::pci_device_enumeration();
+ boot_time.event("pci enumerated");
+ }
// Initialize all drivers
hw::driver_manager* drvman = hw::driver_manager::instance();
@@ -167,15 +178,23 @@ void arch_init_drivers()
void arch_init_early_console()
{
+ if (is_xen()) {
+ new (&console::aarch64_console.xen) console::XEN_Console();
+ console::arch_early_console = console::aarch64_console.xen;
+ return;
+ }
+
+ new (&console::aarch64_console.pl011) console::PL011_Console();
+ console::arch_early_console = console::aarch64_console.pl011;
int irqid;
u64 addr = dtb_get_uart(&irqid);
if (!addr) {
/* keep using default addresses */
return;
}
- console::arch_early_console.set_base_addr(addr);
- console::arch_early_console.set_irqid(irqid);
+ console::aarch64_console.pl011.set_base_addr(addr);
+ console::aarch64_console.pl011.set_irqid(irqid);
}
bool arch_setup_console(std::string opt_console)
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -31,6 +31,9 @@ start_elf:
str x5, [x1, #:lo12:dtb]
mov x29, xzr
+ bl init_xen
+
+ mov x29, xzr
bl premain
adrp x3, __argc
diff --git a/arch/aarch64/early-console.cc b/arch/aarch64/early-console.cc
--- a/arch/aarch64/early-console.cc
+++ b/arch/aarch64/early-console.cc
@@ -5,11 +5,14 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
-#include "drivers/pl011.hh"
#include <osv/prio.hh>
+#include "early-console.hh"
+#include "xen.hh"
+
namespace console {
-PL011_Console arch_early_console
__attribute__((init_priority((int)init_prio::console)));
+union AARCH64_Console aarch64_console;
+console_driver & arch_early_console = aarch64_console.pl011;
}
diff --git a/arch/aarch64/early-console.hh b/arch/aarch64/early-console.hh
--- a/arch/aarch64/early-console.hh
+++ b/arch/aarch64/early-console.hh
@@ -8,11 +8,22 @@
#ifndef EARLY_CONSOLE_HH
#define EARLY_CONSOLE_HH
-#include "drivers/pl011.hh"
+#include <drivers/console-driver.hh>
+#include <drivers/pl011.hh>
+#include <drivers/xenconsole.hh>
namespace console {
-extern PL011_Console arch_early_console;
+union AARCH64_Console {
+ PL011_Console pl011;
+ XEN_Console xen;
+
+ AARCH64_Console() {}; /* placement new is used to initialize object */
+ ~AARCH64_Console() {}; /* won't ever be called */
+};
+
+extern AARCH64_Console aarch64_console;
+extern console_driver & arch_early_console;
}
diff --git a/arch/aarch64/hypercall.S b/arch/aarch64/hypercall.S
--- a/arch/aarch64/hypercall.S
+++ b/arch/aarch64/hypercall.S
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 Sergiy Kibrik <sergiy.kib...@globallogic.com>
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include <xen/interface/xen.h>
+
+#define _hypercall(call) \
+ .align 16; \
+ .globl HYPERVISOR_##call; \
+ .type HYPERVISOR_##call , "function"; \
+ HYPERVISOR_##call: \
+ mov x16, #__HYPERVISOR_##call; \
+ hvc 0xEA1; \
+ ret;
+
+.text
+_hypercall(sched_op)
+_hypercall(memory_op)
+_hypercall(multicall)
+_hypercall(event_channel_op)
+_hypercall(xen_version)
+_hypercall(console_io)
+_hypercall(physdev_op)
+_hypercall(grant_table_op)
+_hypercall(vcpu_op)
+_hypercall(platform_op_raw)
+_hypercall(hvm_op)
diff --git a/arch/aarch64/preboot.S b/arch/aarch64/preboot.S
--- a/arch/aarch64/preboot.S
+++ b/arch/aarch64/preboot.S
@@ -11,6 +11,30 @@ target = . + 0x10000
.text
.align 16
+_head:
+ /* Image header expected by Linux boot-loaders, see
+ * Documentation/arm64/booting.txt in Linux tree for format description
+ */
+ b prestart // jump to actual prestart
+ .long 0 // reserved
+ .long 0x00080000 // image load offset
+ .long 0x00000000
+ .long 0 // unused image size -- already known by
+ .long 0 // image loader, thus ignored
+ .long 0 // unused informative flags, Xen/QEMU
+ .long 0 // image loaders ignore this field
+ .long 0 // reserved
+ .long 0 // reserved
+ .long 0 // reserved
+ .long 0 // reserved
+ .long 0 // reserved
+ .long 0 // reserved
+ .byte 0x41 // magic number, "ARM\x64"
+ .byte 0x52
+ .byte 0x4d
+ .byte 0x64
+ .long 0 // reserved
+
.globl prestart
prestart: // x4 = 0x40080000 set by qemu bootloader
mov x5, x0 /* save device tree blob addr */
diff --git a/arch/aarch64/xen.cc b/arch/aarch64/xen.cc
--- a/arch/aarch64/xen.cc
+++ b/arch/aarch64/xen.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 Sergiy Kibrik <sergiy.kib...@globallogic.com>
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include <osv/types.h>
+#include <xen/interface/xen.h>
+
+#include "arch-dtb.hh"
+#include "xen.hh"
+
+shared_info_t *HYPERVISOR_shared_info;
+
+namespace xen {
+
+shared_info_t dummy_info;
+
+}
+
+extern "C" {
+
+void init_xen()
+{
+ HYPERVISOR_shared_info = nullptr;
+ if (dtb_get_vmm_is_xen()) {
+ /* set valid pointer just to know we're under Xen.
+ * Real shared page will be set up later, when page allocator
works.
+ */
+ HYPERVISOR_shared_info = &xen::dummy_info;
+ }
+}
+}
diff --git a/arch/aarch64/xen.hh b/arch/aarch64/xen.hh
--- a/arch/aarch64/xen.hh
+++ b/arch/aarch64/xen.hh
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2017 Sergiy Kibrik <sergiy.kib...@globallogic.com>
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef XEN_HH
+#define XEN_HH
+#include <xen/interface/xen.h>
+
+extern "C" shared_info_t *HYPERVISOR_shared_info;
+
+#define is_xen() (HYPERVISOR_shared_info != nullptr)
+
+#endif /* XEN_HH */
diff --git a/bsd/aarch64/machine/xen/hypercall.h
b/bsd/aarch64/machine/xen/hypercall.h
--- a/bsd/aarch64/machine/xen/hypercall.h
+++ b/bsd/aarch64/machine/xen/hypercall.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 Sergiy Kibrik <sergiy.kib...@globallogic.com>
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef __MACHINE_XEN_HYPERCALL_H__
+#define __MACHINE_XEN_HYPERCALL_H__
+
+#include <xen/interface/xen.h>
+
+#define ENOXENSYS 38
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int HYPERVISOR_sched_op(int cmd, void *arg);
+int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
+int HYPERVISOR_multicall(multicall_entry_t *call_list, unsigned int
nr_calls);
+int HYPERVISOR_event_channel_op(int cmd, void *arg);
+int HYPERVISOR_xen_version(int cmd, void *arg);
+int HYPERVISOR_console_io(int cmd, unsigned int count, char *str);
+int HYPERVISOR_physdev_op(int cmd, void *arg);
+int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int
count);
+int HYPERVISOR_vcpu_op(int cmd, unsigned int vcpuid, void *extra_args);
+int HYPERVISOR_platform_op_raw(struct xen_platform_op *platform_op);
+unsigned long HYPERVISOR_hvm_op(int op, void *arg);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+static inline int
+HYPERVISOR_platform_op(struct xen_platform_op *platform_op)
+{
+ platform_op->interface_version = XENPF_INTERFACE_VERSION;
+ return HYPERVISOR_platform_op_raw(platform_op);
+}
+
+static inline int
+HYPERVISOR_suspend(unsigned long mfn)
+{
+ struct sched_shutdown sched_shutdown = {
+ .reason = SHUTDOWN_suspend
+ };
+
+ return HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
+}
+
+static inline int
+HYPERVISOR_sched_op_compat(
+ int cmd, unsigned long arg)
+{
+ abort();
+}
+
+static inline int
+HYPERVISOR_update_va_mapping(
+ unsigned long va, uint64_t new_val, unsigned long flags)
+{
+ abort();
+}
+
+static inline int
+HYPERVISOR_mmu_update(
+ mmu_update_t *req, unsigned int count, unsigned int *success_count,
+ domid_t domid)
+{
+ abort();
+}
+#endif /* __MACHINE_XEN_HYPERCALL_H__ */
diff --git a/bsd/sys/xen/hypervisor.h b/bsd/sys/xen/hypervisor.h
--- a/bsd/sys/xen/hypervisor.h
+++ b/bsd/sys/xen/hypervisor.h
@@ -58,9 +58,9 @@ extern start_info_t *xen_start_info;
extern uint64_t get_system_time(int ticks);
static inline int
-HYPERVISOR_console_write(char *str, int count)
+HYPERVISOR_console_write(const char *str, int count)
{
- return HYPERVISOR_console_io(CONSOLEIO_write, count, str);
+ return HYPERVISOR_console_io(CONSOLEIO_write, count,
const_cast<char*>(str));
}
static inline void HYPERVISOR_crash(void) __dead2;
diff --git a/bsd/sys/xen/interface/arch-aarch64.h
b/bsd/sys/xen/interface/arch-aarch64.h
--- a/bsd/sys/xen/interface/arch-aarch64.h
+++ b/bsd/sys/xen/interface/arch-aarch64.h
@@ -0,0 +1,52 @@
+/*
+ * arch-aarch64.h
+ *
+ * based on arch-x86/xen.h
+ *
+ * Copyright (C) 2017 Sergiy Kibrik <sergiy.kib...@globallogic.com>
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+
+*/
+
+#include "xen.h"
+
+#ifndef __XEN_PUBLIC_ARCH_AARCH64_H__
+#define __XEN_PUBLIC_ARCH_AARCH64_H__
+
+#define ___DEFINE_XEN_GUEST_HANDLE(name, type)
\
+ typedef struct { type *p; } __guest_handle_##name
+
+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
+ ___DEFINE_XEN_GUEST_HANDLE(name, type); \
+ ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
+
+#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name,
name)
+#define XEN_GUEST_HANDLE(name) __guest_handle_##name
+
+#define __HYPERVISOR_platform_op_raw __HYPERVISOR_platform_op
+
+/* Maximum number of virtual CPUs in multi-processor guests. */
+#define MAX_VIRT_CPUS 1
+
+#ifndef __ASSEMBLY__
+typedef uint64_t xen_pfn_t;
+#define PRI_xen_pfn "llx"
+typedef uint64_t xen_ulong_t;
+#define PRI_xen_ulong "llx"
+
+struct arch_vcpu_info {
+};
+typedef struct arch_vcpu_info arch_vcpu_info_t;
+
+struct arch_shared_info {
+};
+
+typedef struct arch_shared_info arch_shared_info_t;
+
+typedef unsigned long xen_callback_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __XEN_PUBLIC_ARCH_AARCH64_H__ */
diff --git a/bsd/sys/xen/interface/xen.h b/bsd/sys/xen/interface/xen.h
--- a/bsd/sys/xen/interface/xen.h
+++ b/bsd/sys/xen/interface/xen.h
@@ -33,6 +33,8 @@
#include "arch-x86/xen.h"
#elif defined(__ia64__)
#include "arch-ia64.h"
+#elif defined(__aarch64__)
+#include "arch-aarch64.h"
#else
#error "Unsupported architecture"
#endif
diff --git a/compiler/include/intrinsics.hh b/compiler/include/intrinsics.hh
--- a/compiler/include/intrinsics.hh
+++ b/compiler/include/intrinsics.hh
@@ -2,7 +2,7 @@
#ifndef COMPILER_INTRINSICS_HH
#define COMPILER_INTRINSICS_HH
-#ifndef ASSEMBLY
+#ifndef __ASSEMBLY__
#if __GNUC__ == 4 && __GNUC_MINOR__ < 8
diff --git a/drivers/xenconsole.cc b/drivers/xenconsole.cc
--- a/drivers/xenconsole.cc
+++ b/drivers/xenconsole.cc
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 Sergiy Kibrik <sergiy.kib...@globallogic.com>
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include <bsd/porting/netport.h> /* __dead2 defined here */
+#include <xen/hypervisor.h>
+
+#include "xenconsole.hh"
+
+namespace console {
+
+void XEN_Console::write(const char *str, size_t len) {
+ HYPERVISOR_console_write(str, len);
+}
+
+void XEN_Console::dev_start()
+{
+}
+
+void XEN_Console::flush()
+{
+}
+
+bool XEN_Console::input_ready()
+{
+ return false; /*TODO: support input */
+}
+
+char XEN_Console::readch() {
+ return '\0'; /*TODO: support input */
+}
+
+}
diff --git a/drivers/xenconsole.hh b/drivers/xenconsole.hh
--- a/drivers/xenconsole.hh
+++ b/drivers/xenconsole.hh
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Sergiy Kibrik <sergiy.kib...@globallogic.com>
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef XEN_CONSOLE_HH
+#define XEN_CONSOLE_HH
+
+#include "console-driver.hh"
+#include "exceptions.hh"
+#include <osv/interrupt.hh>
+
+namespace console {
+
+class XEN_Console : public console_driver {
+public:
+ virtual void write(const char *str, size_t len);
+ virtual void flush();
+ virtual bool input_ready();
+ virtual char readch();
+
+private:
+ virtual void dev_start();
+ virtual const char *thread_name() { return "xen-input"; }
+};
+
+}
+
+#endif /* XEN_CONSOLE_HH */
--
You received this message because you are subscribed to the Google Groups "OSv
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.