*~
+*.o
+*.d
+/arch/x86/*.lds
+/cscope.*
+/dist/
/docs/autogenerated/
+/tests/*/test-*
+.PHONY: all
+all:
+ @for D in $(wildcard tests/*); do \
+ $(MAKE) -C $$D build; \
+ done
+
+.PHONY: install
+install:
+ @for D in $(wildcard tests/*); do \
+ $(MAKE) -C $$D install; \
+ done
+
+.PHONY: cscope
+cscope:
+ find include/ arch/ common/ tests/ -name "*.[hcsS]" > cscope.files
+ cscope -b -q -k
+
+.PHONY: clean
+clean:
+ find . \( -name "*.o" -o -name "*.d" -o -name "*.lds" \) -delete
+ find tests/ -executable -name "test-*" -delete
+
+.PHONY: distclean
+distclean: clean
+ find . -name "*~" -delete
+ rm -f cscope.*
+ rm -rf docs/autogenerated/ dist/
+
.PHONY: doxygen
doxygen: Doxyfile
doxygen Doxyfile
## The framework consists of:
-* Nothing (yet)
+* PV 32 and 64 bit entry points
## TODO List:
* More introductory text
-* Entry points for 32 and 64bit PV and HVM guests
+* Entry points for 32 and 64bit HVM guests
* Hypercall infrastructure
* PV console driver
* Common reporting framework
--- /dev/null
+#include <xtf/asm_macros.h>
+
+#include <xen/elfnote.h>
+
+/* Guest name and version */
+ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "XTF")
+ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "0")
+
+/* PV loader */
+ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic")
+
+/* Xen ABI information */
+ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
+ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz "!writable_page_tables|pae_pgdir_above_4gb")
+ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes")
+
+ .text
+#ifdef __x86_64__
+ .code64
+#else
+ .code32
+#endif
+
+ /* PV entry point. */
+GLOBAL(_start)
+ call xtf_main
+ ud2
+SIZE(_start)
--- /dev/null
+/*
+ * Common linker file for all x86 environments
+ */
+
+/* Don't clobber the ld directive */
+#undef i386
+
+#if defined(__x86_64__)
+
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+
+#elif defined(__i386__)
+
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+
+#else
+# error Bad architecture to link with
+#endif
+
+ENTRY(_start)
+
+SECTIONS
+{
+ . = 0x10000;
+
+ .text : {
+ *(.text)
+ } = 0x9090
+
+ .rodata : {
+ *(.rodata)
+ *(.rodata.*)
+ }
+
+ .note : {
+ *(.note)
+ *(.note.*)
+ }
+}
--- /dev/null
+/**
+ * @file common/setup.c
+ *
+ * C entry point.
+ */
+
+#include <xtf/test.h>
+
+/**
+ * Entry point into C.
+ *
+ * Set up the microkernel and invoke the test.
+ */
+void xtf_main(void)
+{
+ test_main();
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+ROOT := $(abspath $(CURDIR)/../..)
+DESTDIR ?= $(ROOT)/dist/
+
+PV_ENVIRONMENTS := pv64 pv32
+ALL_ENVIRONMENTS := $(PV_ENVIRONMENTS)
+
+pv64_arch := x86_64
+pv32_arch := x86_32
+
+COMMON_FLAGS := -pipe -I$(ROOT)/include -MMD -MP
+
+COMMON_AFLAGS := $(COMMON_FLAGS) -D__ASSEMBLY__
+COMMON_CFLAGS := $(COMMON_FLAGS) -Wall -Wextra -Werror -std=gnu99 -Wstrict-prototypes -O3 -g
+COMMON_CFLAGS += -fno-common -fno-asynchronous-unwind-tables -fno-strict-aliasing
+COMMON_CFLAGS += -fno-stack-protector -flto -ffreestanding
+COMMON_CFLAGS += -mno-red-zone -mno-sse
+
+COMMON_AFLAGS-x86_32 := -m32
+COMMON_AFLAGS-x86_64 := -m64
+
+COMMON_CFLAGS-x86_32 := -m32
+COMMON_CFLAGS-x86_64 := -m64
+
+head-pv64 := $(ROOT)/arch/x86/boot/head_pv64.o
+head-pv32 := $(ROOT)/arch/x86/boot/head_pv32.o
+
+obj-perarch :=
+obj-perenv :=
+include $(ROOT)/config/files.mk
+
+# Run once per environment to set up some common bits & pieces
+define PERENV_setup
+
+AFLAGS_$($(1)_arch) := $$(COMMON_AFLAGS) $$(COMMON_AFLAGS-$($(1)_arch))
+CFLAGS_$($(1)_arch) := $$(COMMON_CFLAGS) $$(COMMON_CFLAGS-$($(1)_arch))
+
+AFLAGS_$(1) := $$(AFLAGS_$($(1)_arch)) $$(COMMON_AFLAGS-$(1)) -DCONFIG_ENV_$(1)
+CFLAGS_$(1) := $$(CFLAGS_$($(1)_arch)) $$(COMMON_CFLAGS-$(1)) -DCONFIG_ENV_$(1)
+
+link-$(1) := $(ROOT)/arch/x86/link-$(1).lds
+
+LDFLAGS_$(1) := -T $$(link-$(1))
+
+# Needs to pick up test-provided obj-perenv and obj-perarch
+DEPS-$(1) = $(head-$(1)) \
+ $$(obj-perarch:%.o=%-$($(1)_arch).o) \
+ $$(obj-$(1):%.o=%-$(1).o) $$(obj-perenv:%.o=%-$(1).o)
+
+# Generate head with approprate flags
+ifneq ($(findstring $(1),$(PV_ENVIRONMENTS)),)
+# PV guests generate head_pv64.o and head_pv32.o from head_pv.S
+%/head_$(1).o: %/head_pv.S
+ $$(CC) $$(AFLAGS_$(1)) -c $$< -o $$@
+endif
+
+# Generate .lds with approprate flags
+%/link-$(1).lds: %/link.lds.S
+ $$(CC) -E $$(AFLAGS_$(1)) -P -C $$< -o $$@
+
+# Generate a per-arch .o from .S
+%-$($(1)_arch).o: %.S
+ $$(CC) $$(AFLAGS_$$((1)_arch)) -c $$< -o $$@
+
+# Generate a per-arch .o from .c
+%-$($(1)_arch).o: %.c
+ $$(CC) $$(CFLAGS_$($(1)_arch)) -c $$< -o $$@
+
+# Generate a per-env .o from .S
+%-$(1).o: %.S
+ $$(CC) $$(AFLAGS_$(1)) -c $$< -o $$@
+
+# Generate a per-env .o from .c
+%-$(1).o: %.c
+ $$(CC) $$(CFLAGS_$(1)) -c $$< -o $$@
+
+endef
+
+$(foreach env,$(ALL_ENVIRONMENTS),$(eval $(call PERENV_setup,$(env))))
+
--- /dev/null
+# Files compiled and linked for different architectures and environments
+#
+# obj-perarch get compiled once per architecture
+# obj-perenv get get compiled once for each environment
+# obj-$(env) are objects unique to a specific environment
+
+obj-perarch += $(ROOT)/common/setup.o
--- /dev/null
+
+# Sanity checking of expected parameters
+
+ifeq ($(NAME),)
+$(error NAME should be specified)
+endif
+
+ifeq ($(TEST-ENVS),)
+$(error TEST-ENVS should not be empty)
+endif
+
+ifneq ($(filter-out $(ALL_ENVIRONMENTS),$(TEST-ENVS)),)
+$(error Unrecognised environments '$(filter-out $(ALL_ENVIRONMENTS),$(TEST-ENVS))')
+endif
+
+.PHONY: build
+build: $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME))
+
+.PHONY: install install-each-env
+install: install-each-env
+
+define PERENV_build
+
+test-$(1)-$(NAME): $$(DEPS-$(1)) $$(link-$(1))
+ $$(LD) $$(LDFLAGS_$(1)) $$(DEPS-$(1)) -o $$@
+
+-include $$(link-$(1):%.lds=%.d)
+-include $$(DEPS-$(1):%.o=%.d)
+
+.PHONY: install-$(1)
+install-$(1): test-$(1)-$(NAME)
+ @mkdir -p $(DESTDIR)
+ install -m775 -p $$< $(DESTDIR)
+install-each-env: install-$(1)
+
+endef
+$(foreach env,$(TEST-ENVS),$(eval $(call PERENV_build,$(env))))
+
+.PHONY: clean
+clean:
+ find $(ROOT) \( -name "*.o" -o -name "*.d" \) -delete
+ rm -f $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME))
+
+.PHONY: %var
+%var:
+ @echo "$* = $($*)"
--- /dev/null
+/*
+ * Xen public elfnote reference
+ */
+
+#ifndef XEN_PUBLIC_ELFNOTE_H
+#define XEN_PUBLIC_ELFNOTE_H
+
+#define XEN_ELFNOTE_XEN_VERSION 5
+#define XEN_ELFNOTE_GUEST_OS 6
+#define XEN_ELFNOTE_GUEST_VERSION 7
+#define XEN_ELFNOTE_LOADER 8
+#define XEN_ELFNOTE_PAE_MODE 9
+#define XEN_ELFNOTE_FEATURES 10
+
+#endif /* XEN_PUBLIC_ELFNOTE_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+/**
+ * @file include/xtf/asm_macros.h
+ *
+ * Macros for use in assembly files.
+ */
+#ifndef XTF_ASM_MACROS_H
+#define XTF_ASM_MACROS_H
+
+/**
+ * Declare a global symbol.
+ * @param name Symbol name.
+ */
+#define GLOBAL(name) \
+ .globl name; \
+name:
+
+/**
+ * Set the size of a named symbol.
+ * @param name Symbol name.
+ */
+#define SIZE(name) \
+ .size name, . - name;
+
+/**
+ * Create an ELF note entry.
+ *
+ * 'desc' may be an arbitrary asm construct.
+ */
+#define ELFNOTE(name, type, desc) \
+ .pushsection .note.name ; \
+ .align 4 ; \
+ .long 2f - 1f /* namesz */ ; \
+ .long 4f - 3f /* descsz */ ; \
+ .long type /* type */ ; \
+1:.asciz #name /* name */ ; \
+2:.align 4 ; \
+3:desc /* desc */ ; \
+4:.align 4 ; \
+ .popsection
+
+#endif /* XTF_ASM_MACROS_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+/**
+ * @file include/xtf/test.h
+ *
+ * API for tests.
+ */
+#ifndef XTF_TEST_H
+#define XTF_TEST_H
+
+/**
+ * To be implemented by each test, as its entry point.
+ */
+void test_main(void);
+
+#endif /* XTF_TEST_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+ROOT := $(abspath $(CURDIR)/../..)
+
+include $(ROOT)/config/common.mk
+
+NAME := example
+TEST-ENVS := $(ALL_ENVIRONMENTS)
+
+obj-perenv += main.o
+
+include $(ROOT)/config/gen.mk
--- /dev/null
+#include <xtf/test.h>
+
+void test_main(void)
+{
+ for ( ; ; )
+ asm volatile ("rep; nop");
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */