diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 139816067..437086a4a 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -19,10 +19,6 @@ HV_OBJDIR ?= $(CURDIR)/build HV_MODDIR ?= $(HV_OBJDIR)/modules HV_FILE := acrn -ifeq ($(TARGET_DIR),) - override TARGET_DIR := $(realpath ../misc/vm_configs) -endif - LIB_MOD = $(HV_MODDIR)/lib_mod.a BOOT_MOD = $(HV_MODDIR)/boot_mod.a HW_MOD = $(HV_MODDIR)/hw_mod.a @@ -47,20 +43,10 @@ ARCH_LDFLAGS := .PHONY: default default: all -include scripts/makefile/cfg_update.mk +include scripts/makefile/config.mk -include scripts/makefile/deps.mk - -include scripts/makefile/kconfig.mk - -#override BOARD from CONFIG_BOARD, which is specified in kconfig.mk -override BOARD := $(shell echo $(CONFIG_BOARD) |sed 's/"//g') - -#override SCENARIO from CONFIG_SCENARIO, which is specified in kconfig.mk -override SCENARIO := $(shell echo $(CONFIG_SCENARIO) |sed 's/"//g') - -BOARD_INFO_DIR := $(TARGET_DIR)/boards/$(BOARD) -SCENARIO_CFG_DIR := $(TARGET_DIR)/scenarios/$(SCENARIO) +BOARD_INFO_DIR := $(HV_CONFIG_DIR)/boards/$(BOARD) +SCENARIO_CFG_DIR := $(HV_CONFIG_DIR)/scenarios/$(SCENARIO) BOARD_CFG_DIR := $(SCENARIO_CFG_DIR)/$(BOARD) include ../paths.make @@ -147,27 +133,27 @@ ARCH_LDFLAGS += ARCH_LDSCRIPT = $(HV_OBJDIR)/link_ram.ld ARCH_LDSCRIPT_IN = bsp/ld/link_ram.ld.in -INCLUDE_PATH += include -INCLUDE_PATH += include/lib -INCLUDE_PATH += include/lib/crypto -INCLUDE_PATH += include/common -INCLUDE_PATH += include/arch/x86 -INCLUDE_PATH += include/arch/x86/boot -INCLUDE_PATH += include/arch/x86/guest -INCLUDE_PATH += include/arch/x86/lib -INCLUDE_PATH += include/debug -INCLUDE_PATH += include/public -INCLUDE_PATH += include/dm -INCLUDE_PATH += include/hw -INCLUDE_PATH += boot/include -INCLUDE_PATH += boot/include/guest +REL_INCLUDE_PATH += include +REL_INCLUDE_PATH += include/lib +REL_INCLUDE_PATH += include/lib/crypto +REL_INCLUDE_PATH += include/common +REL_INCLUDE_PATH += include/arch/x86 +REL_INCLUDE_PATH += include/arch/x86/boot +REL_INCLUDE_PATH += include/arch/x86/guest +REL_INCLUDE_PATH += include/arch/x86/lib +REL_INCLUDE_PATH += include/debug +REL_INCLUDE_PATH += include/public +REL_INCLUDE_PATH += include/dm +REL_INCLUDE_PATH += include/hw +REL_INCLUDE_PATH += boot/include +REL_INCLUDE_PATH += boot/include/guest + +INCLUDE_PATH := $(realpath $(REL_INCLUDE_PATH)) INCLUDE_PATH += $(HV_OBJDIR)/include INCLUDE_PATH += $(BOARD_INFO_DIR) INCLUDE_PATH += $(BOARD_CFG_DIR) INCLUDE_PATH += $(SCENARIO_CFG_DIR) -override INCLUDE_PATH := $(realpath $(INCLUDE_PATH)) - CC ?= gcc AS ?= as AR ?= ar @@ -266,9 +252,7 @@ endif VM_CFG_C_SRCS += $(BOARD_INFO_DIR)/board.c VM_CFG_C_SRCS += $(SCENARIO_CFG_DIR)/vm_configurations.c VM_CFG_C_SRCS += $(BOARD_CFG_DIR)/pt_intx.c -ifneq (,$(wildcard $(BOARD_CFG_DIR)/pci_dev.c)) VM_CFG_C_SRCS += $(BOARD_CFG_DIR)/pci_dev.c -endif # virtual platform base component VP_BASE_C_SRCS += arch/x86/guest/vcpuid.c @@ -342,7 +326,7 @@ BOOT_C_OBJS := $(patsubst %.c,$(HV_OBJDIR)/%.o,$(BOOT_C_SRCS)) BOOT_S_OBJS := $(patsubst %.S,$(HV_OBJDIR)/%.o,$(BOOT_S_SRCS)) HW_C_OBJS := $(patsubst %.c,$(HV_OBJDIR)/%.o,$(HW_C_SRCS)) HW_S_OBJS := $(patsubst %.S,$(HV_OBJDIR)/%.o,$(HW_S_SRCS)) -VM_CFG_C_OBJS := $(patsubst %.c,$(HV_OBJDIR)/%.o,$(realpath $(VM_CFG_C_SRCS))) +VM_CFG_C_OBJS := $(patsubst %.c,%.o,$(VM_CFG_C_SRCS)) VP_BASE_C_OBJS := $(patsubst %.c,$(HV_OBJDIR)/%.o,$(VP_BASE_C_SRCS)) VP_BASE_S_OBJS := $(patsubst %.S,$(HV_OBJDIR)/%.o,$(VP_BASE_S_SRCS)) VP_DM_C_OBJS := $(patsubst %.c,$(HV_OBJDIR)/%.o,$(VP_DM_C_SRCS)) @@ -393,15 +377,15 @@ install-debug: $(HV_OBJDIR)/$(HV_FILE).map $(HV_OBJDIR)/$(HV_FILE).out install -D $(HV_OBJDIR)/$(HV_FILE).map $(DESTDIR)$(libdir)/acrn/$(HV_FILE).$(BOARD).$(SCENARIO).map .PHONY: pre_build -pre_build: $(HV_OBJDIR)/$(HV_CONFIG_H) +pre_build: $(HV_CONFIG_H) $(HV_CONFIG_TIMESTAMP) @echo "Start pre-build static check ..." - $(MAKE) -C $(PRE_BUILD_DIR) BOARD=$(BOARD) SCENARIO=$(SCENARIO) TARGET_DIR=$(TARGET_DIR) + $(MAKE) -C $(PRE_BUILD_DIR) BOARD=$(BOARD) SCENARIO=$(SCENARIO) TARGET_DIR=$(HV_CONFIG_DIR) @$(HV_OBJDIR)/hv_prebuild_check.out @echo "generate the binary of ACPI tables for pre-launched VMs ..." - python3 ../misc/acrn-config/acpi_gen/bin_gen.py --board $(BOARD) --scenario $(SCENARIO) --asl $(TARGET_DIR) --out $(HV_OBJDIR)/acpi + python3 ../misc/acrn-config/acpi_gen/bin_gen.py --board $(BOARD) --scenario $(SCENARIO) --asl $(HV_CONFIG_DIR) --out $(HV_OBJDIR)/acpi .PHONY: header -header: $(VERSION) $(HV_OBJDIR)/$(HV_CONFIG_H) +header: $(VERSION) $(HV_CONFIG_H) .PHONY: lib-mod boot-mod hw-mod vp-base-mod vp-dm-mod vp-trusty-mod vp-hcall-mod sys-init-mod $(LIB_MOD): $(LIB_C_OBJS) $(LIB_S_OBJS) @@ -459,7 +443,7 @@ $(HV_OBJDIR)/$(HV_FILE).bin: $(HV_OBJDIR)/$(HV_FILE).out rm -f $(UPDATE_RESULT) $(HV_OBJDIR)/$(HV_FILE).out: $(MODULES) - ${BASH} ${LD_IN_TOOL} $(ARCH_LDSCRIPT_IN) $(ARCH_LDSCRIPT) ${HV_OBJDIR}/.config + ${BASH} ${LD_IN_TOOL} $(ARCH_LDSCRIPT_IN) $(ARCH_LDSCRIPT) ${HV_CONFIG_MK} $(CC) -Wl,-Map=$(HV_OBJDIR)/$(HV_FILE).map -o $@ $(LDFLAGS) $(ARCH_LDFLAGS) -T$(ARCH_LDSCRIPT) \ -Wl,--start-group $^ -Wl,--end-group @@ -476,7 +460,7 @@ distclean: rm -f tags TAGS cscope.files cscope.in.out cscope.out cscope.po.out GTAGS GPATH GRTAGS GSYMS PHONY: (VERSION) -$(VERSION): $(HV_OBJDIR)/$(HV_CONFIG_H) +$(VERSION): $(HV_CONFIG_H) touch $(VERSION) @COMMIT=`git rev-parse --verify --short HEAD 2>/dev/null`;\ DIRTY=`git diff-index --name-only HEAD`;\ @@ -511,10 +495,14 @@ $(VERSION): $(HV_OBJDIR)/$(HV_CONFIG_H) -include $(C_OBJS:.o=.d) -include $(S_OBJS:.o=.d) -$(HV_OBJDIR)/%.o: %.c $(VERSION) $(HV_OBJDIR)/$(HV_CONFIG_H) +$(HV_OBJDIR)/%.o: %.c $(VERSION) $(HV_CONFIG_H) [ ! -e $@ ] && mkdir -p $(dir $@) && mkdir -p $(HV_MODDIR); \ $(CC) $(patsubst %, -I%, $(INCLUDE_PATH)) -I. -c $(CFLAGS) $(ARCH_CFLAGS) $< -o $@ -MMD -MT $@ -$(HV_OBJDIR)/%.o: %.S $(HV_OBJDIR)/$(HV_CONFIG_H) +$(VM_CFG_C_OBJS): %.o: %.c $(VERSION) $(HV_CONFIG_H) + [ ! -e $@ ] && mkdir -p $(dir $@) && mkdir -p $(HV_MODDIR); \ + $(CC) $(patsubst %, -I%, $(INCLUDE_PATH)) -I. -c $(CFLAGS) $(ARCH_CFLAGS) $< -o $@ -MMD -MT $@ + +$(HV_OBJDIR)/%.o: %.S $(HV_CONFIG_H) [ ! -e $@ ] && mkdir -p $(dir $@) && mkdir -p $(HV_MODDIR); \ $(CC) $(patsubst %, -I%, $(INCLUDE_PATH)) -I. $(ASFLAGS) $(ARCH_ASFLAGS) -c $< -o $@ -MMD -MT $@ diff --git a/hypervisor/scripts/makefile/config.mk b/hypervisor/scripts/makefile/config.mk new file mode 100644 index 000000000..920d85725 --- /dev/null +++ b/hypervisor/scripts/makefile/config.mk @@ -0,0 +1,262 @@ +# Copyright (C) 2021 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause + +# usage: check_coexistence +# +# This macro checks if the given symbols are both defined or both not. This is used to check the coexistence of BOARD & +# SCENARIO or BOARD_FILE & SCENARIO_FILE. +define check_coexistence = +ifdef $(1) + ifndef $(2) + $$(warning $(1) is defined while $(2) is empty) + $$(error $(1) & $(2) must be given in pair) + endif +else + ifdef $(2) + $$(warning $(2) is defined while $(1) is empty) + $$(error $(1) & $(2) must be given in pair) + endif +endif +endef + +# usage: determine_config +# +# BOARD and SCENARIO can be specified in the following places. +# +# 1. Configuration data in config.mk (named CONFIG_BOARD or CONFIG_SCENARIO) which are extracted from the existing XML +# file. +# +# 2. Variables defined on the command line when invoking 'make'. +# +# 3. Default values in this script. +# +# In place #2 it can be either a board/scenario name or path to an XML file. Depending on where these variables are +# defined and their values, this script behaves as follows. +# +# * If a variable is defined in both #1 and #2 with the same value, that value is effective for the build. +# +# * If a variable is defined in both #1 and #2 with different values, the build terminates with an error message. +# +# * If a variable is defined in either #1 or #2 (but not both), that value is effective for the build. +# +# * If a variable is defined in neither #1 nor #2, the default value is effective for the build. +# +# If #2 gives a path to an XML file, the board/scenario defined in that file is used for the comparison above. +# +# This macro implements the policy. The following variables will be rewritten after the rules are evaluated without any +# error. +# +# * The (i.e. either BOARD or SCENARIO) will always hold the name of the effective board/scenario. +# +# * The _FILE (i.e. either BOARD_FILE or SCENARIO_FILE) will always hold the path to an existing XML file that +# defines the effective board/scenario. If only a BOARD/SCENARIO name is given, a predefined configuration under +# misc/acrn-config/xmls will be used. +# +define determine_config = +ifneq ($($(1)),) + ifneq ($(realpath $($(1))),) + override $(1)_FILE := $($(1)) + override $(1) := $$(shell xmllint --xpath 'string(/acrn-config/@$(shell echo $(1) | tr A-Z a-z))' $$($(1)_FILE)) + else + override $(1)_FILE := $(HV_PREDEFINED_$(1)_DIR)/$$($(1)).xml + ifeq ($$(realpath $$($(1)_FILE)),) + $$(error $(1) = '$($(1))' is neither path to a file nor name of a predefined board) + endif + endif + ifdef CONFIG_$(1) + ifneq ($$($(1)), $(CONFIG_$(1))) + $$(warning The command line sets $(1) to be '$$($(1))', but an existing build is configured with '$(CONFIG_$(1))') + $$(warning Try cleaning up the existing build with 'make clean' or setting HV_OBJDIR to a newly-created directory) + $$(error Configuration conflict identified) + endif + endif +else + ifdef CONFIG_$(1) + override $(1) := $(CONFIG_$(1)) + else + override $(1) := $(2) + endif + override $(1)_FILE := $(HV_PREDEFINED_$(1)_DIR)/$$($(1)).xml +endif +endef + +# usage: determine_build_type +# +# Similar to BOARD or SCENARIO, the RELEASE variable has three sources where it can be defined. But unlike those +# variables that cannot be modified once configured, users shall be able to tweak RELEASE from the command line even a +# build directory has already been configured. +# +# This macro implements the same check as determine_config, but attempts to update the configuration file if RELEASE is +# changed. +define determine_build_type = +ifdef RELEASE + ifdef CONFIG_RELEASE + ifneq ($(RELEASE),$(CONFIG_RELEASE)) + $$(warning The command line sets RELEASE to be '$(RELEASE)', but an existing build is configured with '$(CONFIG_RELEASE)') + $$(warning The configuration will be modified for RELEASE=$(RELEASE)) + $$(shell sed -i "s@\(\)[yn]\(\)@\1$(RELEASE)\2@g" $(HV_SCENARIO_XML)) + endif + endif +else + ifdef CONFIG_RELEASE + RELEASE := $(CONFIG_RELEASE) + else + RELEASE := $(1) + endif +endif +endef + +# Paths to the inputs +# +# Note: BOARD may not be defined at this point. Thus, HV_PREDEFINED_SCENARIO_DIR is defined using '=' rather than ':=' +# so that the variable will only be expanded when used. +HV_BOARD_XML := $(HV_OBJDIR)/.board.xml +HV_SCENARIO_XML := $(HV_OBJDIR)/.scenario.xml +HV_UNIFIED_XML_IN := $(BASEDIR)/scripts/makefile/unified.xml.in +HV_PREDEFINED_BOARD_DIR := $(realpath $(BASEDIR)/../misc/acrn-config/xmls/board-xmls) +HV_PREDEFINED_SCENARIO_DIR = $(realpath $(BASEDIR)/../misc/acrn-config/xmls/config-xmls)/$(BOARD) +HV_CONFIG_TOOL_DIR := $(realpath $(BASEDIR)/../misc/acrn-config) +HV_CONFIG_XFORM_DIR := $(HV_CONFIG_TOOL_DIR)/xforms + +# Paths to the outputs: +HV_CONFIG_DIR := $(HV_OBJDIR)/configs +HV_ALLOCATION_XML := $(HV_CONFIG_DIR)/allocation.xml +HV_UNIFIED_XML := $(HV_CONFIG_DIR)/unified.xml +HV_CONFIG_H := $(HV_OBJDIR)/include/config.h +HV_CONFIG_MK := $(HV_CONFIG_DIR)/config.mk +HV_CONFIG_TIMESTAMP := $(HV_CONFIG_DIR)/.timestamp + +# Backward-compatibility for RELEASE=(0|1) +ifdef RELEASE + ifeq ($(RELEASE),1) + override RELEASE := y + else + ifeq ($(RELEASE),0) + override RELEASE := n + endif + endif +endif + +ifeq ($(findstring $(MAKECMDGOALS),distclean),) +-include $(HV_CONFIG_MK) +endif + +# BOARD/SCENARIO/BOARD_FILE/SCENARIO_FILE parameters sanity check. +# +# 1. Raise an error if BOARD/SCENARIO (or BOARD_FILE/SCENARIO_FILE) are partially given. +# 2. Raise an error if BOARD_FILE/SCENARIO_FILE are given but do not point to valid XMLs. + +$(eval $(call check_coexistence,BOARD,SCENARIO)) +$(eval $(call check_coexistence,BOARD_FILE,SCENARIO_FILE)) + +# BOARD_FILE/SCENARIO_FILE are to be obsoleted. Users can now use BOARD/SCENARIO to give either pre-defined +# board/scenario or their own XML files. +# +# The following block converts BOARD_FILE/SCENARIO_FILE to BOARD/SCENARIO. Removing support of BOARD_FILE/SCENARIO_FILE +# can be done by simply deleting it. +ifneq ($(BOARD_FILE)$(SCENARIO_FILE),) + $(warning BOARD_FILE/SCENARIO_FILE are obsoleted. Use BOARD/SCENARIO to specify either predefined board/scenario or your own board/scenario XMLs) + + ifneq ($(BOARD)$(SCENARIO),) + $(warning BOARD/SCENARIO and BOARD_FILE/SCENARIO_FILE are both given. BOARD/SCENARIO will take precedence) + else + ifneq ($(BOARD_FILE), $(wildcard $(BOARD_FILE))) + $(error BOARD_FILE: $(BOARD_FILE) does not exist) + endif + ifneq ($(SCENARIO_FILE), $(wildcard $(SCENARIO_FILE))) + $(error SCENARIO_FILE: $(SCENARIO_FILE) does not exist) + endif + BOARD := $(BOARD_FILE) + SCENARIO := $(SCENARIO_FILE) + endif +endif + +# Internally we still use BOARD to represent the name of the target board and BOARD_FILE to be the path to the board XML +# file. SCENARIO/SCENARIO_FILE are used in the same way. The following block translates the user-visible BOARD/SCENARIO +# (which is multiplexed) to the internal representation. + +$(eval $(call determine_config,BOARD,nuc7i7dnb)) +$(eval $(call determine_config,SCENARIO,industry)) +$(eval $(call determine_build_type,y)) + +$(HV_BOARD_XML): + @if [ ! -f $(HV_BOARD_XML) ]; then \ + if [ -f $(BOARD_FILE) ]; then \ + echo "Board XML is fetched from $(realpath $(BOARD_FILE))"; \ + mkdir -p $(dir $(HV_BOARD_XML)); \ + cp $(BOARD_FILE) $(HV_BOARD_XML); \ + else \ + echo "No pre-defined board info available at $(BOARD_FILE)"; \ + echo "Try setting another predefined BOARD or SCENARIO or specifying a board XML file"; \ + exit 1; \ + fi; \ + fi + +$(HV_SCENARIO_XML): + @if [ ! -f $(HV_SCENARIO_XML) ]; then \ + if [ -f $(SCENARIO_FILE) ]; then \ + echo "Scneario XML is configuration fetched from $(realpath $(SCENARIO_FILE))"; \ + mkdir -p $(dir $(HV_SCENARIO_XML)); \ + cp $(SCENARIO_FILE) $(HV_SCENARIO_XML); \ + else \ + echo "No pre-defined scenario available at $(SCENARIO_FILE)"; \ + echo "Try setting another predefined BOARD or SCENARIO or specifying a scenario XML file"; \ + exit 1; \ + fi; \ + fi + +# A unified XML is generated to include board and scenario XML files so that XSLT scripts have access to both for +# generating source files. +$(HV_ALLOCATION_XML): $(HV_BOARD_XML) $(HV_SCENARIO_XML) | $(HV_CONFIG_DIR) + @python3 $(HV_CONFIG_TOOL_DIR)/static_allocators/main.py --board $(HV_BOARD_XML) --scenario $(HV_SCENARIO_XML) --output $(HV_ALLOCATION_XML) + @echo "$@ generated" + +$(HV_UNIFIED_XML): $(HV_BOARD_XML) $(HV_SCENARIO_XML) $(HV_ALLOCATION_XML) | $(HV_CONFIG_DIR) + @sed "s@{BOARD_FILE}@$(realpath $(HV_BOARD_XML))@g" $(HV_UNIFIED_XML_IN) | \ + sed "s@{SCENARIO_FILE}@$(HV_SCENARIO_XML)@g" | \ + sed "s@{ALLOCATION_FILE}@$(HV_ALLOCATION_XML)@g" > $@ + @echo "$@ generated" + +$(HV_CONFIG_MK): $(HV_UNIFIED_XML) | $(HV_CONFIG_DIR) + @xsltproc -o $@ --xinclude --xincludestyle $(HV_CONFIG_XFORM_DIR)/config.mk.xsl $< + @echo "$@ generated" + +$(HV_CONFIG_H): $(HV_UNIFIED_XML) + @mkdir -p $(dir $(HV_CONFIG_H)) + @xsltproc -o $@ --xinclude --xincludestyle $(HV_CONFIG_XFORM_DIR)/config.h.xsl $< + @echo "$@ generated" + +$(HV_CONFIG_TIMESTAMP): $(HV_UNIFIED_XML) | $(HV_CONFIG_DIR) + @sh $(BASEDIR)/scripts/genconf.sh $(BASEDIR) $(HV_BOARD_XML) $(HV_SCENARIO_XML) $(HV_CONFIG_DIR) + @touch $@ + +.PHONY: defconfig +defconfig: $(HV_CONFIG_TIMESTAMP) + +showconfig: + @echo "Build directory: $(HV_OBJDIR)" + @echo "This build directory is configured with the settings below." + @echo "- BOARD = $(BOARD)" + @echo "- SCENARIO = $(SCENARIO)" + @echo "- RELEASE = $(RELEASE)" + +menuconfig: + @echo "To tweak the configurations, run $(HV_CONFIG_TOOL_DIR)/config_app/app.py using python3 and load $(HV_SCENARIO_XML) in the web browser." + +$(HV_CONFIG_DIR): + @mkdir -p $@ + +# Legacy variables and targets +ifdef TARGET_DIR + $(warning TARGET_DIR is obsoleted because generated configuration files are now stored in the build directory) +endif + +oldconfig: + @echo "Generated configuration files are now automatically updated with the scenario XML file." + @echo "There is no need to invoke oldconfig manually anymore." + +update_config: + @echo "Generated configuration files are now automatically updated with the scenario XML file." + @echo "There is no need to invoke update_config manually anymore." + +CFLAGS += -include $(HV_CONFIG_H) diff --git a/misc/hv_prebuild/Makefile b/misc/hv_prebuild/Makefile index 0e5ecdeeb..3717c835e 100644 --- a/misc/hv_prebuild/Makefile +++ b/misc/hv_prebuild/Makefile @@ -18,8 +18,8 @@ ifeq ($(TARGET_DIR),) $(error please specify VM configs directory! ) endif -BOARD_INFO_DIR := $(TARGET_DIR)/boards/$(BOARD) -SCENARIO_CFG_DIR := $(TARGET_DIR)/scenarios/$(SCENARIO) +BOARD_INFO_DIR := $(HV_OBJDIR)/configs/boards/$(BOARD) +SCENARIO_CFG_DIR := $(HV_OBJDIR)/configs/scenarios/$(SCENARIO) BOARD_CFG_DIR := $(SCENARIO_CFG_DIR)/$(BOARD) PRE_BUILD_SRCS += main.c