# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = __attribute__(x)= \
+ __noreturn \
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
## The framework consists of:
* PV 32 and 64 bit entry points
+* Hypercall interface
## TODO List:
* More introductory text
* Entry points for 32 and 64bit HVM guests
-* Hypercall infrastructure
* PV console driver
* Common reporting framework
* Tests
/* PV loader */
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic")
+ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _WORD hypercall_page)
/* Xen ABI information */
ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
--- /dev/null
+#include <arch/x86/page.h>
+#include <xtf/asm_macros.h>
+#include <xen/xen.h>
+
+.text
+.align PAGE_SIZE
+GLOBAL(hypercall_page)
+ /* Poisoned with `ret` for safety before hypercalls are set up. */
+ .fill PAGE_SIZE, 1, 0xc3
+ .size hypercall_page, PAGE_SIZE
+
+DECLARE_HYPERCALL(sched_op)
* C entry point.
*/
+#include <xtf/compiler.h>
+#include <xtf/hypercall.h>
#include <xtf/test.h>
/**
*
* Set up the microkernel and invoke the test.
*/
-void xtf_main(void)
+void __noreturn xtf_main(void)
{
test_main();
+
+ hypercall_shutdown(SHUTDOWN_poweroff);
+ unreachable();
}
/*
# obj-$(env) are objects unique to a specific environment
obj-perarch += $(ROOT)/common/setup.o
+
+# Always link hypercall_page.S last as it is a page of data replaced by the hyperisor
+obj-perenv += $(ROOT)/arch/x86/hypercall_page.o
--- /dev/null
+#ifndef XTF_X86_PAGE_H
+#define XTF_X86_PAGE_H
+
+/*
+ * Nomenclature inherited from Xen.
+ */
+
+#define PAGE_SHIFT 12
+
+#ifdef __ASSEMBLY__
+#define PAGE_SIZE (1 << PAGE_SHIFT)
+#else
+#define PAGE_SIZE (1L << PAGE_SHIFT)
+#endif
+
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+
+#endif /* XTF_X86_PAGE_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+#ifndef XTF_X86_32_HYPERCALL_H
+#define XTF_X86_32_HYPERCALL_H
+
+/*
+ * Hypercall primatives for 32bit
+ *
+ * Inputs: %ebx, %ecx, %edx, %esi, %edi, %ebp (arguments 1-6)
+ */
+
+#define _hypercall32_2(type, name, a1, a2) \
+ ({ \
+ long __res, __ign1, __ign2; \
+ asm volatile ( \
+ "call hypercall_page + %c[offset]" \
+ : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
+ : [offset] "i" (__HYPERVISOR_##name * 32), \
+ "1" ((long)(a1)), "2" ((long)(a2)) \
+ : "memory" ); \
+ (type)__res; \
+ })
+
+#endif /* XTF_X86_32_HYPERCALL_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+#ifndef XTF_X86_64_HYPERCALL_H
+#define XTF_X86_64_HYPERCALL_H
+
+/*
+ * Hypercall primatives for 64bit
+ *
+ * Inputs: %rdi, %rsi, %rdx, %r10, %r8, %r9 (arguments 1-6)
+ */
+
+#define _hypercall64_2(type, name, a1, a2) \
+ ({ \
+ long __res, __ign1, __ign2; \
+ asm volatile ( \
+ "call hypercall_page + %c[offset]" \
+ : "=a" (__res), "=D" (__ign1), "=S" (__ign2) \
+ : [offset] "i" (__HYPERVISOR_##name * 32), \
+ "1" ((long)(a1)), "2" ((long)(a2)) \
+ : "memory" ); \
+ (type)__res; \
+ })
+
+#endif /* XTF_X86_64_HYPERCALL_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
#ifndef XEN_PUBLIC_ELFNOTE_H
#define XEN_PUBLIC_ELFNOTE_H
+#define XEN_ELFNOTE_HYPERCALL_PAGE 2
#define XEN_ELFNOTE_XEN_VERSION 5
#define XEN_ELFNOTE_GUEST_OS 6
#define XEN_ELFNOTE_GUEST_VERSION 7
--- /dev/null
+/*
+ * Xen public xen_version hypercall interface
+ */
+
+#ifndef XEN_PUBLIC_SCHED_H
+#define XEN_PUBLIC_SCHED_H
+
+#define SCHEDOP_shutdown 2
+
+#ifndef __ASSEMBLY__
+struct sched_shutdown {
+ unsigned int reason; /* SHUTDOWN_* */
+};
+#endif
+
+#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */
+#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */
+#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */
+#define SHUTDOWN_crash 3 /* Tell controller we've crashed. */
+#define SHUTDOWN_watchdog 4 /* Restart because watchdog time expired. */
+
+#endif /* XEN_PUBLIC_SCHED_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+/*
+ * Xen public hypercall interface
+ */
+
+#ifndef XEN_PUBLIC_XEN_H
+#define XEN_PUBLIC_XEN_H
+
+#define __HYPERVISOR_sched_op 29
+
+#endif /* XEN_PUBLIC_XEN_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
#ifndef XTF_ASM_MACROS_H
#define XTF_ASM_MACROS_H
+/* Declare data at the architectures width. */
+#if defined(__x86_64__)
+# define _WORD .quad
+#elif defined(__i386__)
+# define _WORD .long
+#else
+# error Bad architecture for _WORD
+#endif
+
/**
* Declare a global symbol.
* @param name Symbol name.
#define SIZE(name) \
.size name, . - name;
+/**
+ * Identify a specific hypercall in the hypercall page
+ * @param name Hypercall name.
+ */
+#define DECLARE_HYPERCALL(name) \
+ .globl HYPERCALL_ ## name; \
+ .set HYPERCALL_ ## name, hypercall_page + __HYPERVISOR_ ## name * 32; \
+ .size HYPERCALL_ ## name, 32
+
/**
* Create an ELF note entry.
*
--- /dev/null
+#ifndef XTF_COMPILER_H
+#define XTF_COMPILER_H
+
+#define __noreturn __attribute__((noreturn))
+#define unreachable() __builtin_unreachable()
+
+#endif /* XTF_COMPILER_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+#ifndef XTF_HYPERCALL_H
+#define XTF_HYPERCALL_H
+
+#include <xtf/types.h>
+
+#if defined(__x86_64__)
+
+# include <arch/x86/x86_64/hypercall-x86_64.h>
+# define HYPERCALL2 _hypercall64_2
+
+#elif defined(__i386__)
+
+# include <arch/x86/x86_32/hypercall-x86_32.h>
+# define HYPERCALL2 _hypercall32_2
+
+#else
+# error Bad architecture for hypercalls
+#endif
+
+/* All Xen ABI for includers convenience .*/
+#include <xen/xen.h>
+#include <xen/sched.h>
+
+/*
+ * Hypercall primatives, compiled for the correct bitness
+ */
+static inline long hypercall_sched_op(unsigned int cmd, void *arg)
+{
+ return HYPERCALL2(long, sched_op, cmd, arg);
+}
+
+/*
+ * Higher level hypercall helpers
+ */
+static inline long hypercall_shutdown(unsigned int reason)
+{
+ return hypercall_sched_op(SCHEDOP_shutdown, &reason);
+}
+
+#endif /* XTF_HYPERCALL_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+#ifndef XTF_TYPES_H
+#define XTF_TYPES_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdarg.h>
+
+#define __need_size_t
+#define __need_ptrsize_t
+#define __need_NULL
+#include <stddef.h>
+
+#endif /* XTF_TYPES_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
void test_main(void)
{
- for ( ; ; )
- asm volatile ("rep; nop");
}
/*