Currently XTF build system is strictly made up for x86.
Modify the build system so that it will be easier
to add other platforms to XTF in the future.
This is done by generalizing the common makefiles to be
architecture independent and creating architecture
specific makefiles.
Signed-off-by: Michal Orzel <michal.orzel@arm.com>
xtftestdir := $(xtfdir)/tests
-export DESTDIR xtfdir xtftestdir
+# Supported architectures
+SUPPORTED_ARCH := x86
+# Default architecture
+ARCH ?= x86
+# Check if specified architecture is supported
+ifeq ($(filter $(ARCH),$(SUPPORTED_ARCH)),)
+$(error Architecture '$(ARCH)' not supported)
+endif
+
+export DESTDIR ARCH xtfdir xtftestdir
ifeq ($(LLVM),) # GCC toolchain
CC := $(CROSS_COMPILE)gcc
export CC LD CPP INSTALL INSTALL_DATA INSTALL_DIR INSTALL_PROGRAM OBJCOPY PYTHON
# By default enable all the tests
-TESTS ?= $(wildcard $(ROOT)/tests/*)
+TESTS ?= $(wildcard tests/*)
.PHONY: all
all:
+# Architecture independent/common configuration
ALL_CATEGORIES := special functional xsa utility in-development
-ALL_ENVIRONMENTS := pv64 pv32pae hvm64 hvm32pae hvm32pse hvm32
-
-PV_ENVIRONMENTS := $(filter pv%,$(ALL_ENVIRONMENTS))
-HVM_ENVIRONMENTS := $(filter hvm%,$(ALL_ENVIRONMENTS))
-32BIT_ENVIRONMENTS := $(filter pv32% hvm32%,$(ALL_ENVIRONMENTS))
-64BIT_ENVIRONMENTS := $(filter pv64% hvm64%,$(ALL_ENVIRONMENTS))
-
-# $(env)_guest => pv or hvm mapping
-$(foreach env,$(PV_ENVIRONMENTS),$(eval $(env)_guest := pv))
-$(foreach env,$(HVM_ENVIRONMENTS),$(eval $(env)_guest := hvm))
-
-# $(env)_arch => x86_32/64 mapping
-$(foreach env,$(32BIT_ENVIRONMENTS),$(eval $(env)_arch := x86_32))
-$(foreach env,$(64BIT_ENVIRONMENTS),$(eval $(env)_arch := x86_64))
-
comma := ,
-COMMON_FLAGS := -pipe -nostdinc -I$(ROOT)/include -I$(ROOT)/arch/x86/include -MMD -MP
+COMMON_FLAGS := -pipe -nostdinc -I$(ROOT)/include -I$(ROOT)/arch/$(ARCH)/include -MMD -MP
cc-option = $(shell if [ -z "`echo 'int p=1;' | $(CC) $(1) -c -o /dev/null -x c - 2>&1`" ]; \
then echo y; else echo n; fi)
COMMON_AFLAGS := $(COMMON_FLAGS) $(COMMON_AFLAGS-y) -D__ASSEMBLY__
COMMON_CFLAGS := $(COMMON_FLAGS) $(COMMON_CFLAGS-y)
+
+# Include architecture specific configuration
+include $(ROOT)/build/$(ARCH)/arch-common.mk
+
+COMMON_CFLAGS += -I$(ARCH_PATH)/include
+COMMON_AFLAGS += -I$(ARCH_PATH)/include
COMMON_CFLAGS += -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 -fno-pic -ffreestanding
-COMMON_CFLAGS += -mno-red-zone -mno-sse
COMMON_CFLAGS += -Wno-unused-parameter -Winline
-COMMON_AFLAGS-x86_32 := -m32
-COMMON_AFLAGS-x86_64 := -m64
-
-COMMON_CFLAGS-x86_32 := -m32
-COMMON_CFLAGS-x86_64 := -m64
-
+# Default guest configfiles
defcfg-pv := $(ROOT)/config/default-pv.cfg.in
defcfg-hvm := $(ROOT)/config/default-hvm.cfg.in
+# Following variables needs to be set up in $(ROOT)/build/$(ARCH)/arch-files.mk
+# obj-perbits get compiled once per bitness
+# obj-perenv get compiled once for each environment
+# obj-$(env) are objects unique to a specific environment
obj-perbits :=
obj-perenv :=
-include $(ROOT)/build/files.mk
-# Run once per environment to set up some common bits & pieces
+include $(ROOT)/build/$(ARCH)/arch-files.mk
+
+# Set up some common bits and pieces for specified environment
define PERENV_setup
AFLAGS_$($(1)_arch) := $$(COMMON_AFLAGS) $$(COMMON_AFLAGS-$($(1)_arch))
AFLAGS_$(1) := $$(AFLAGS_$($(1)_arch)) $$(COMMON_AFLAGS-$(1)) -DCONFIG_ENV_$(1) -include arch/config.h
CFLAGS_$(1) := $$(CFLAGS_$($(1)_arch)) $$(COMMON_CFLAGS-$(1)) -DCONFIG_ENV_$(1) -include arch/config.h
-link-$(1) := $(ROOT)/arch/x86/link-$(1).lds
+link-$(1) := $(ARCH_PATH)/link-$(1).lds
LDFLAGS_$(1) := -T $$(link-$(1)) -nostdlib $(LDFLAGS-y)
endef
+# Make a call to a function PERENV_setup once per each environment
$(foreach env,$(ALL_ENVIRONMENTS),$(eval $(call PERENV_setup,$(env))))
define move-if-changed
+++ /dev/null
-# Files compiled and linked for different architectures and environments
-#
-# obj-perbits get compiled once per bitness
-# obj-perenv get get compiled once for each environment
-# obj-$(env) are objects unique to a specific environment
-
-obj-perbits += $(ROOT)/common/console.o
-obj-perbits += $(ROOT)/common/exlog.o
-obj-perbits += $(ROOT)/common/extable.o
-obj-perbits += $(ROOT)/common/grant_table.o
-obj-perbits += $(ROOT)/common/heapsort.o
-obj-perbits += $(ROOT)/common/lib.o
-obj-perbits += $(ROOT)/common/libc/stdio.o
-obj-perbits += $(ROOT)/common/libc/string.o
-obj-perbits += $(ROOT)/common/libc/vsnprintf.o
-obj-perbits += $(ROOT)/common/report.o
-obj-perbits += $(ROOT)/common/setup.o
-obj-perbits += $(ROOT)/common/xenbus.o
-obj-perbits += $(ROOT)/common/weak-defaults.o
-
-obj-perenv += $(ROOT)/arch/x86/decode.o
-obj-perenv += $(ROOT)/arch/x86/desc.o
-obj-perenv += $(ROOT)/arch/x86/extable.o
-obj-perenv += $(ROOT)/arch/x86/grant_table.o
-obj-perenv += $(ROOT)/arch/x86/hypercall_page.o
-obj-perenv += $(ROOT)/arch/x86/msr.o
-obj-perenv += $(ROOT)/arch/x86/setup.o
-obj-perenv += $(ROOT)/arch/x86/traps.o
-
-
-# HVM specific objects
-obj-hvm += $(ROOT)/arch/x86/apic.o
-obj-hvm += $(ROOT)/arch/x86/hpet.o
-obj-hvm += $(ROOT)/arch/x86/hvm/head.o
-obj-hvm += $(ROOT)/arch/x86/hvm/pagetables.o
-obj-hvm += $(ROOT)/arch/x86/hvm/traps.o
-obj-hvm += $(ROOT)/arch/x86/io-apic.o
-
-# Arguably common objects, but PV guests will have no interest in them.
-obj-hvm += $(ROOT)/arch/x86/vmx.o
-obj-hvm += $(ROOT)/arch/x86/x86-tss.o
-
-$(foreach env,$(HVM_ENVIRONMENTS),$(eval obj-$(env) += $(obj-hvm)))
-
-
-# PV specific objects
-obj-pv += $(ROOT)/arch/x86/pv/head.o
-obj-pv += $(ROOT)/arch/x86/pv/traps.o
-$(foreach env,$(PV_ENVIRONMENTS),$(eval obj-$(env) += $(obj-pv)))
-
-
-# 32bit specific objects
-obj-32 += $(ROOT)/arch/x86/entry_32.o
-$(foreach env,$(32BIT_ENVIRONMENTS),$(eval obj-$(env) += $(obj-32)))
-
-
-# 64bit specific objects
-obj-64 += $(ROOT)/arch/x86/entry_64.o
-$(foreach env,$(64BIT_ENVIRONMENTS),$(eval obj-$(env) += $(obj-64)))
+# Architecture independent makefile for compiling tests
# Sanity checking of expected parameters
@$(INSTALL_DIR) $(DESTDIR)$(xtftestdir)/$(NAME)
$(INSTALL_DATA) info.json $(DESTDIR)$(xtftestdir)/$(NAME)
-hvm64-format := $(firstword $(filter elf32-x86-64,$(shell $(OBJCOPY) --help)) elf32-i386)
-
+# Build a test for specified environment
define PERENV_build
-ifneq ($(1),hvm64)
-# Generic link line for most environments
+# If any environment needs a special compilation/linking recipe instead of
+# the default one, a custom recipe called build-$(env) e.g. build-hvm64
+# should be created in $(ROOT)/build/$(ARCH)/arch-common.mk
+
test-$(1)-$(NAME): $$(DEPS-$(1)) $$(link-$(1))
+ifndef build-$(1)
+ @# Generic link line for most environments
$(LD) $$(LDFLAGS_$(1)) $$(DEPS-$(1)) -o $$@
else
-# hvm64 needs linking normally, then converting to elf32-x86-64 or elf32-i386
-test-$(1)-$(NAME): $$(DEPS-$(1)) $$(link-$(1))
- $(LD) $$(LDFLAGS_$(1)) $$(DEPS-$(1)) -o $$@.tmp
- $(OBJCOPY) $$@.tmp -O $(hvm64-format) $$@
- rm -f $$@.tmp
+ @# Environment specific compilation recipe
+ $(call build-$(1))
endif
cfg-$(1) ?= $(defcfg-$($(1)_guest))
install-each-env: install-$(1) install-$(1).cfg
endef
+
+# Make a call to a function PERENV_build once per each test's environment
$(foreach env,$(TEST-ENVS),$(eval $(call PERENV_build,$(env))))
.PHONY: clean
--- /dev/null
+# Architecture specific configuration for x86
+
+ARCH_PATH := $(ROOT)/arch/x86
+ALL_ENVIRONMENTS := pv64 pv32pae hvm64 hvm32pae hvm32pse hvm32
+
+PV_ENVIRONMENTS := $(filter pv%,$(ALL_ENVIRONMENTS))
+HVM_ENVIRONMENTS := $(filter hvm%,$(ALL_ENVIRONMENTS))
+32BIT_ENVIRONMENTS := $(filter pv32% hvm32%,$(ALL_ENVIRONMENTS))
+64BIT_ENVIRONMENTS := $(filter pv64% hvm64%,$(ALL_ENVIRONMENTS))
+
+# $(env)_guest => pv or hvm mapping
+$(foreach env,$(PV_ENVIRONMENTS),$(eval $(env)_guest := pv))
+$(foreach env,$(HVM_ENVIRONMENTS),$(eval $(env)_guest := hvm))
+
+# $(env)_arch => x86_32/64 mapping
+$(foreach env,$(32BIT_ENVIRONMENTS),$(eval $(env)_arch := x86_32))
+$(foreach env,$(64BIT_ENVIRONMENTS),$(eval $(env)_arch := x86_64))
+
+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
+
+hvm64-format := $(firstword $(filter elf32-x86-64,$(shell $(OBJCOPY) --help)) elf32-i386)
+
+# Compilation recipe for hvm64
+# hvm64 needs linking normally, then converting to elf32-x86-64 or elf32-i386
+define build-hvm64
+ $(LD) $$(LDFLAGS_hvm64) $$(DEPS-hvm64) -o $$@.tmp
+ $(OBJCOPY) $$@.tmp -O $(hvm64-format) $$@
+ rm -f $$@.tmp
+endef
--- /dev/null
+# Architecture specific files compiled and linked for x86
+
+# Per bitness
+obj-perbits += $(ROOT)/common/console.o
+obj-perbits += $(ROOT)/common/exlog.o
+obj-perbits += $(ROOT)/common/extable.o
+obj-perbits += $(ROOT)/common/grant_table.o
+obj-perbits += $(ROOT)/common/heapsort.o
+obj-perbits += $(ROOT)/common/lib.o
+obj-perbits += $(ROOT)/common/libc/stdio.o
+obj-perbits += $(ROOT)/common/libc/string.o
+obj-perbits += $(ROOT)/common/libc/vsnprintf.o
+obj-perbits += $(ROOT)/common/report.o
+obj-perbits += $(ROOT)/common/setup.o
+obj-perbits += $(ROOT)/common/xenbus.o
+obj-perbits += $(ROOT)/common/weak-defaults.o
+
+# Per environment
+obj-perenv += $(ROOT)/arch/x86/decode.o
+obj-perenv += $(ROOT)/arch/x86/desc.o
+obj-perenv += $(ROOT)/arch/x86/extable.o
+obj-perenv += $(ROOT)/arch/x86/grant_table.o
+obj-perenv += $(ROOT)/arch/x86/hypercall_page.o
+obj-perenv += $(ROOT)/arch/x86/msr.o
+obj-perenv += $(ROOT)/arch/x86/setup.o
+obj-perenv += $(ROOT)/arch/x86/traps.o
+
+
+# HVM specific objects
+obj-hvm += $(ROOT)/arch/x86/apic.o
+obj-hvm += $(ROOT)/arch/x86/hpet.o
+obj-hvm += $(ROOT)/arch/x86/hvm/head.o
+obj-hvm += $(ROOT)/arch/x86/hvm/pagetables.o
+obj-hvm += $(ROOT)/arch/x86/hvm/traps.o
+obj-hvm += $(ROOT)/arch/x86/io-apic.o
+
+# Arguably common objects, but PV guests will have no interest in them.
+obj-hvm += $(ROOT)/arch/x86/vmx.o
+obj-hvm += $(ROOT)/arch/x86/x86-tss.o
+
+$(foreach env,$(HVM_ENVIRONMENTS),$(eval obj-$(env) += $(obj-hvm)))
+
+
+# PV specific objects
+obj-pv += $(ROOT)/arch/x86/pv/head.o
+obj-pv += $(ROOT)/arch/x86/pv/traps.o
+$(foreach env,$(PV_ENVIRONMENTS),$(eval obj-$(env) += $(obj-pv)))
+
+
+# 32bit specific objects
+obj-32 += $(ROOT)/arch/x86/entry_32.o
+$(foreach env,$(32BIT_ENVIRONMENTS),$(eval obj-$(env) += $(obj-32)))
+
+
+# 64bit specific objects
+obj-64 += $(ROOT)/arch/x86/entry_64.o
+$(foreach env,$(64BIT_ENVIRONMENTS),$(eval obj-$(env) += $(obj-64)))