From: Andrew Cooper Date: Tue, 17 Mar 2015 23:15:02 +0000 (+0100) Subject: Basic build system and pv32/64 stubs. They currently spin in a loop X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=df88c7eb23d6655f04778ecf8c2c5fd829b6f62d;p=people%2Froyger%2Fxen-test-framework.git Basic build system and pv32/64 stubs. They currently spin in a loop Signed-off-by: Andrew Cooper --- diff --git a/.gitignore b/.gitignore index 7d77218..a63215e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,8 @@ *~ +*.o +*.d +/arch/x86/*.lds +/cscope.* +/dist/ /docs/autogenerated/ +/tests/*/test-* diff --git a/Makefile b/Makefile index fcbe499..e2a9068 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,31 @@ +.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 diff --git a/README b/README index 2b528bd..b7b48be 100644 --- a/README +++ b/README @@ -11,12 +11,12 @@ machine. ## 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 diff --git a/arch/x86/boot/head_pv.S b/arch/x86/boot/head_pv.S new file mode 100644 index 0000000..bdf4136 --- /dev/null +++ b/arch/x86/boot/head_pv.S @@ -0,0 +1,28 @@ +#include + +#include + +/* 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) diff --git a/arch/x86/link.lds.S b/arch/x86/link.lds.S new file mode 100644 index 0000000..22f48a2 --- /dev/null +++ b/arch/x86/link.lds.S @@ -0,0 +1,41 @@ +/* + * 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.*) + } +} diff --git a/common/setup.c b/common/setup.c new file mode 100644 index 0000000..a0a66a4 --- /dev/null +++ b/common/setup.c @@ -0,0 +1,27 @@ +/** + * @file common/setup.c + * + * C entry point. + */ + +#include + +/** + * 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: + */ diff --git a/config/common.mk b/config/common.mk new file mode 100644 index 0000000..89fc75e --- /dev/null +++ b/config/common.mk @@ -0,0 +1,79 @@ +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)))) + diff --git a/config/files.mk b/config/files.mk new file mode 100644 index 0000000..b19ecc7 --- /dev/null +++ b/config/files.mk @@ -0,0 +1,7 @@ +# 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 diff --git a/config/gen.mk b/config/gen.mk new file mode 100644 index 0000000..dcf7c52 --- /dev/null +++ b/config/gen.mk @@ -0,0 +1,46 @@ + +# 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 "$* = $($*)" diff --git a/include/xen/elfnote.h b/include/xen/elfnote.h new file mode 100644 index 0000000..05716f4 --- /dev/null +++ b/include/xen/elfnote.h @@ -0,0 +1,25 @@ +/* + * 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: + */ diff --git a/include/xtf/asm_macros.h b/include/xtf/asm_macros.h new file mode 100644 index 0000000..c8cfeeb --- /dev/null +++ b/include/xtf/asm_macros.h @@ -0,0 +1,51 @@ +/** + * @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: + */ diff --git a/include/xtf/test.h b/include/xtf/test.h new file mode 100644 index 0000000..5fa84ee --- /dev/null +++ b/include/xtf/test.h @@ -0,0 +1,24 @@ +/** + * @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: + */ diff --git a/tests/example/Makefile b/tests/example/Makefile new file mode 100644 index 0000000..02654e6 --- /dev/null +++ b/tests/example/Makefile @@ -0,0 +1,10 @@ +ROOT := $(abspath $(CURDIR)/../..) + +include $(ROOT)/config/common.mk + +NAME := example +TEST-ENVS := $(ALL_ENVIRONMENTS) + +obj-perenv += main.o + +include $(ROOT)/config/gen.mk diff --git a/tests/example/main.c b/tests/example/main.c new file mode 100644 index 0000000..678d448 --- /dev/null +++ b/tests/example/main.c @@ -0,0 +1,17 @@ +#include + +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: + */