Add the PV/PVH entry point and the low level functions for PVH
initialization.
---
sys/amd64/amd64/locore.S | 53 +++
sys/amd64/amd64/machdep.c| 72 ++
sys/amd64/include/asmacros.h | 26 +++
sys/i386/xen/xen_machdep.c |2 +
sys/x86/xen/hvm.c|1 +
sys/xen/xen-os.h |4 ++
6 files changed, 158 insertions(+), 0 deletions(-)
diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S
index 55cda3a..e04cc48 100644
--- a/sys/amd64/amd64/locore.S
+++ b/sys/amd64/amd64/locore.S
@@ -31,6 +31,12 @@
#include
#include
+#ifdef XENHVM
+#include
+#define __ASSEMBLY__
+#include
+#endif
+
#include "assym.s"
/*
@@ -86,3 +92,50 @@ NON_GPROF_ENTRY(btext)
ALIGN_DATA /* just to be sure */
.space 0x1000 /* space for bootstack - temporary
stack */
bootstack:
+
+#ifdef XENHVM
+/* Xen */
+.section __xen_guest
+ ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "FreeBSD")
+ ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, "HEAD")
+ ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,.asciz, "xen-3.0")
+ ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .quad, KERNBASE)
+ ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .quad, KERNBASE) /* Xen
honours elf->p_paddr; compensate for this */
+ ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .quad, xen_start)
+ ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad, hypercall_page)
+ ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .quad, HYPERVISOR_VIRT_START)
+ ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz,
"writable_descriptor_tables|auto_translated_physmap|supervisor_mode_kernel|hvm_callback_vector")
+ ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes")
+ ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V)
+ ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
+ ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 0)
+ ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB, .asciz, "yes")
+
+ .text
+.p2align PAGE_SHIFT, 0x90 /* Hypercall_page needs to be PAGE aligned */
+
+NON_GPROF_ENTRY(hypercall_page)
+ .skip 0x1000, 0x90/* Fill with "nop"s */
+
+NON_GPROF_ENTRY(xen_start)
+ /* Don't trust what the loader gives for rflags. */
+ pushq $PSL_KERNEL
+ popfq
+
+ /* Parameters for the xen init function */
+ movq%rsi, %rdi /* shared_info (arg 1) */
+ movq%rsp, %rsi /* xenstack(arg 2) */
+
+ /* Use our own stack */
+ movq$bootstack,%rsp
+ xorl%ebp, %ebp
+
+ /* u_int64_t hammer_time_xen(start_info_t *si, u_int64_t xenstack); */
+ callhammer_time_xen
+ movq%rax, %rsp /* set up kstack for mi_startup() */
+ callmi_startup /* autoconfiguration, mountroot etc */
+
+ /* NOTREACHED */
+0: hlt
+ jmp 0b
+#endif
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index eae657b..a73e33e 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -146,10 +146,17 @@ __FBSDID("$FreeBSD$");
#include
#include
+#ifdef XENHVM
+#include
+#endif
+
/* Sanity check for __curthread() */
CTASSERT(offsetof(struct pcpu, pc_curthread) == 0);
extern u_int64_t hammer_time(u_int64_t, u_int64_t);
+#ifdef XENHVM
+extern u_int64_t hammer_time_xen(start_info_t *, u_int64_t);
+#endif
extern void printcpuinfo(void);/* XXX header file */
extern void identify_cpu(void);
@@ -1683,6 +1690,71 @@ do_next:
msgbufp = (struct msgbuf *)PHYS_TO_DMAP(phys_avail[pa_indx]);
}
+#ifdef XENHVM
+/*
+ * First function called by the Xen PVH boot sequence.
+ *
+ * Set some Xen global variables and prepare the environment so it is
+ * as similar as possible to what native FreeBSD init function expects.
+ */
+u_int64_t
+hammer_time_xen(start_info_t *si, u_int64_t xenstack)
+{
+ u_int64_t physfree;
+ u_int64_t *PT4 = (u_int64_t *)xenstack;
+ u_int64_t *PT3 = (u_int64_t *)(xenstack + PAGE_SIZE);
+ u_int64_t *PT2 = (u_int64_t *)(xenstack + 2 * PAGE_SIZE);
+ int i;
+
+ KASSERT((si != NULL && xenstack != 0),
+ ("invalid start_info or xenstack"));
+
+ /* We use 3 pages of xen stack for the boot pagetables */
+ physfree = xenstack + 3 * PAGE_SIZE - KERNBASE;
+
+ /* Setup Xen global variables */
+ HYPERVISOR_start_info = si;
+ HYPERVISOR_shared_info =
+ (shared_info_t *)(si->shared_info + KERNBASE);
+
+ /*
+* Setup some misc global variables for Xen devices
+*
+* XXX: devices that need this specific variables should
+* be rewritten to fetch this info by themselves from the
+* start_info page.
+*/
+ xen_store = (struct xenstore_domain_interface *)
+ (ptoa(si->store_mfn