summaryrefslogtreecommitdiffstats
path: root/make_helpers
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 17:43:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 17:43:51 +0000
commitbe58c81aff4cd4c0ccf43dbd7998da4a6a08c03b (patch)
tree779c248fb61c83f65d1f0dc867f2053d76b4e03a /make_helpers
parentInitial commit. (diff)
downloadarm-trusted-firmware-be58c81aff4cd4c0ccf43dbd7998da4a6a08c03b.tar.xz
arm-trusted-firmware-be58c81aff4cd4c0ccf43dbd7998da4a6a08c03b.zip
Adding upstream version 2.10.0+dfsg.upstream/2.10.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'make_helpers')
-rw-r--r--make_helpers/arch_features.mk333
-rw-r--r--make_helpers/armv7-a-cpus.mk58
-rw-r--r--make_helpers/build_env.mk72
-rw-r--r--make_helpers/build_macros.mk683
-rw-r--r--make_helpers/cygwin.mk19
-rw-r--r--make_helpers/defaults.mk375
-rw-r--r--make_helpers/march.mk85
-rw-r--r--make_helpers/msys.mk20
-rw-r--r--make_helpers/plat_helpers.mk38
-rw-r--r--make_helpers/tbbr/tbbr_tools.mk146
-rw-r--r--make_helpers/unix.mk60
-rw-r--r--make_helpers/windows.mk92
12 files changed, 1981 insertions, 0 deletions
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
new file mode 100644
index 0000000..a337e76
--- /dev/null
+++ b/make_helpers/arch_features.mk
@@ -0,0 +1,333 @@
+#
+# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# This file lists all of the architectural features, and initializes
+# and enables them based on the configured architecture version.
+
+# This file follows the following format:
+# - Enable mandatory feature if applicable to an Arch Version.
+# - By default disable any mandatory features if they have not been defined yet.
+# - Disable or enable any optional feature this would be enabled/disabled if needed by platform.
+
+#
+################################################################################
+# Enable Mandatory features based on Arch versions.
+################################################################################
+#
+
+# Enable the features which are mandatory from ARCH version 8.1 and upwards.
+ifeq "8.1" "$(word 1, $(sort 8.1 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_PAN := 1
+ENABLE_FEAT_VHE := 1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.2 and upwards.
+ifeq "8.2" "$(word 1, $(sort 8.2 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_RAS := 1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.4 and upwards.
+ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_SEL2 := 1
+ENABLE_TRF_FOR_NS := 1
+ENABLE_FEAT_DIT := 1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.5 and upwards.
+ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_RNG := 1
+ENABLE_FEAT_SB := 1
+
+# Enable Memory tagging, Branch Target Identification for aarch64 only.
+ifeq ($(ARCH), aarch64)
+ mem_tag_arch_support := yes
+endif #(ARCH=aarch64)
+
+endif
+
+# Enable the features which are mandatory from ARCH version 8.6 and upwards.
+ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_ECV := 1
+ENABLE_FEAT_FGT := 1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.7 and upwards.
+ifeq "8.7" "$(word 1, $(sort 8.7 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_HCX := 1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.9 and upwards.
+ifeq "8.9" "$(word 1, $(sort 8.9 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_TCR2 := 1
+endif
+
+#
+################################################################################
+# Set mandatory features by default to zero.
+################################################################################
+#
+
+#----
+# 8.1
+#----
+
+# Flag to enable access to Privileged Access Never bit of PSTATE.
+ENABLE_FEAT_PAN ?= 0
+
+# Flag to enable Virtualization Host Extensions.
+ENABLE_FEAT_VHE ?= 0
+
+#----
+# 8.2
+#----
+
+# Enable RAS Support.
+ENABLE_FEAT_RAS ?= 0
+
+#----
+# 8.3
+#----
+
+# Flag to enable Pointer Authentication. Internal flag not meant for
+# direct setting. Use BRANCH_PROTECTION to enable PAUTH.
+ENABLE_PAUTH ?= 0
+
+# Include pointer authentication (ARMv8.3-PAuth) registers in cpu context. This
+# must be set to 1 if the platform wants to use this feature in the Secure
+# world. It is not necessary for use in the Non-secure world.
+CTX_INCLUDE_PAUTH_REGS ?= 0
+
+
+#----
+# 8.4
+#----
+
+# Flag to enable Secure EL-2 feature.
+ENABLE_FEAT_SEL2 ?= 0
+
+# By default, disable trace filter control register access to lower non-secure
+# exception levels, i.e. NS-EL2, or NS-EL1 if NS-EL2 is implemented, but
+# trace filter control register access is unused if FEAT_TRF is implemented.
+ENABLE_TRF_FOR_NS ?= 0
+
+# Flag to enable Data Independent Timing instructions.
+ENABLE_FEAT_DIT ?= 0
+
+#----
+# 8.5
+#----
+
+# Flag to enable Branch Target Identification.
+# Internal flag not meant for direct setting.
+# Use BRANCH_PROTECTION to enable BTI.
+ENABLE_BTI ?= 0
+
+# Flag to enable access to the Random Number Generator registers.
+ENABLE_FEAT_RNG ?= 0
+
+# Flag to enable Speculation Barrier Instruction.
+ENABLE_FEAT_SB ?= 0
+
+#----
+# 8.6
+#----
+
+# Flag to enable access to the CNTPOFF_EL2 register.
+ENABLE_FEAT_ECV ?= 0
+
+# Flag to enable access to the HDFGRTR_EL2 register.
+ENABLE_FEAT_FGT ?= 0
+
+#----
+# 8.7
+#----
+
+# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
+ENABLE_FEAT_HCX ?= 0
+
+#----
+# 8.9
+#----
+
+# Flag to enable access to TCR2 (FEAT_TCR2).
+ENABLE_FEAT_TCR2 ?= 0
+
+#
+################################################################################
+# Optional Features defaulted to 0 or 2, if they are not enabled from
+# build option. Can also be disabled or enabled by platform if needed.
+################################################################################
+#
+
+#----
+# 8.0
+#----
+
+# Flag to enable CSV2_2 extension.
+ENABLE_FEAT_CSV2_2 ?= 0
+
+# By default, disable access of trace system registers from NS lower
+# ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
+# system register trace is implemented. This feature is available if
+# trace unit such as ETMv4.x, This feature is OPTIONAL and is only
+# permitted in Armv8 implementations.
+ENABLE_SYS_REG_TRACE_FOR_NS ?= 0
+
+#----
+# 8.2
+#----
+
+# Build option to enable/disable the Statistical Profiling Extension,
+# keep it enabled by default for AArch64.
+ifeq (${ARCH},aarch64)
+ ENABLE_SPE_FOR_NS ?= 2
+else ifeq (${ARCH},aarch32)
+ ifneq ($(or $(ENABLE_SPE_FOR_NS),0),0)
+ $(error ENABLE_SPE_FOR_NS is not supported for AArch32)
+ else
+ ENABLE_SPE_FOR_NS := 0
+ endif
+endif
+
+# Enable SVE for non-secure world by default.
+ifeq (${ARCH},aarch64)
+ ENABLE_SVE_FOR_NS ?= 2
+# SVE is only supported on AArch64 so disable it on AArch32.
+else ifeq (${ARCH},aarch32)
+ ifneq ($(or $(ENABLE_SVE_FOR_NS),0),0)
+ $(error ENABLE_SVE_FOR_NS is not supported for AArch32)
+ else
+ ENABLE_SVE_FOR_NS := 0
+ endif
+endif
+
+#----
+# 8.4
+#----
+
+# Feature flags for supporting Activity monitor extensions.
+ENABLE_FEAT_AMU ?= 0
+ENABLE_AMU_AUXILIARY_COUNTERS ?= 0
+ENABLE_AMU_FCONF ?= 0
+AMU_RESTRICT_COUNTERS ?= 0
+
+# Build option to enable MPAM for lower ELs.
+# Enabling it by default
+ifeq (${ARCH},aarch64)
+ ENABLE_FEAT_MPAM ?= 2
+else ifeq (${ARCH},aarch32)
+ ifneq ($(or $(ENABLE_FEAT_MPAM),0),0)
+ $(error ENABLE_FEAT_MPAM is not supported for AArch32)
+ else
+ ENABLE_FEAT_MPAM := 0
+ endif
+endif
+
+# Include nested virtualization control (Armv8.4-NV) registers in cpu context.
+# This must be set to 1 if architecture implements Nested Virtualization
+# Extension and platform wants to use this feature in the Secure world.
+CTX_INCLUDE_NEVE_REGS ?= 0
+
+#----
+# 8.5
+#----
+
+# Flag to enable support for EL3 trapping of reads of the RNDR and RNDRRS
+# registers, by setting SCR_EL3.TRNDR.
+ENABLE_FEAT_RNG_TRAP ?= 0
+
+# Include Memory Tagging Extension registers in cpu context. This must be set
+# to 1 if the platform wants to use this feature in the Secure world and MTE is
+# enabled at ELX.
+CTX_INCLUDE_MTE_REGS ?= 0
+
+#----
+# 8.6
+#----
+
+# Flag to enable AMUv1p1 extension.
+ENABLE_FEAT_AMUv1p1 ?= 0
+
+# Flag to enable delayed trapping of WFE instruction (FEAT_TWED).
+ENABLE_FEAT_TWED ?= 0
+
+# In v8.6+ platforms with delayed trapping of WFE being supported
+# via FEAT_TWED, this flag takes the delay value to be set in the
+# SCR_EL3.TWEDEL(4bit) field, when FEAT_TWED is implemented.
+# By default it takes 0, and need to be updated by the platforms.
+TWED_DELAY ?= 0
+
+# Disable MTPMU if FEAT_MTPMU is supported.
+DISABLE_MTPMU ?= 0
+
+#----
+# 8.9
+#----
+
+# Flag to enable NoTagAccess memory region attribute for stage 2 of translation.
+ENABLE_FEAT_MTE_PERM ?= 0
+
+# Flag to enable access to Stage 2 Permission Indirection (FEAT_S2PIE).
+ENABLE_FEAT_S2PIE ?= 0
+
+# Flag to enable access to Stage 1 Permission Indirection (FEAT_S1PIE).
+ENABLE_FEAT_S1PIE ?= 0
+
+# Flag to enable access to Stage 2 Permission Overlay (FEAT_S2POE).
+ENABLE_FEAT_S2POE ?= 0
+
+# Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE).
+ENABLE_FEAT_S1POE ?= 0
+
+#----
+# 9.0
+#----
+
+# Flag to enable Realm Management Extension (FEAT_RME).
+ENABLE_RME ?= 0
+
+# Scalable Matrix Extension for non-secure world.
+ENABLE_SME_FOR_NS ?= 0
+
+# Scalable Vector Extension for secure world.
+ENABLE_SVE_FOR_SWD ?= 0
+
+# By default, disable access of trace buffer control registers from NS
+# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
+# if FEAT_TRBE is implemented.
+# Note FEAT_TRBE is only supported on AArch64 - therefore do not enable in
+# AArch32.
+ifeq (${ARCH},aarch64)
+ ENABLE_TRBE_FOR_NS ?= 0
+else ifeq (${ARCH},aarch32)
+ ifneq ($(or $(ENABLE_TRBE_FOR_NS),0),0)
+ $(error ENABLE_TRBE_FOR_NS is not supported for AArch32)
+ else
+ ENABLE_TRBE_FOR_NS := 0
+ endif
+endif
+
+#----
+# 9.2
+#----
+
+# Scalable Matrix Extension version 2 for non-secure world.
+ENABLE_SME2_FOR_NS ?= 0
+
+# Scalable Matrix Extension for secure world.
+ENABLE_SME_FOR_SWD ?= 0
+
+# By default, disable access to branch record buffer control registers from NS
+# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
+# if FEAT_BRBE is implemented.
+ENABLE_BRBE_FOR_NS ?= 0
+
+#----
+#9.4
+#----
+
+# Flag to enable access to Guarded Control Stack (FEAT_GCS).
+ENABLE_FEAT_GCS ?= 0
diff --git a/make_helpers/armv7-a-cpus.mk b/make_helpers/armv7-a-cpus.mk
new file mode 100644
index 0000000..a8e9d50
--- /dev/null
+++ b/make_helpers/armv7-a-cpus.mk
@@ -0,0 +1,58 @@
+#
+# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch32)
+$(error ARM_ARCH_MAJOR=7 mandates ARCH=aarch32)
+endif
+
+# For ARMv7, set march32 from platform directive ARMV7_CORTEX_Ax=yes
+# and ARM_WITH_NEON=yes/no.
+#
+# GCC and Clang require -march=armv7-a for C-A9 and -march=armv7ve for C-A15.
+# armClang requires -march=armv7-a for all ARMv7 Cortex-A. To comply with
+# all, just drop -march and supply only -mcpu.
+
+# Platform can override march-directive through MARCH_DIRECTIVE
+ifdef MARCH_DIRECTIVE
+march-directive := $(MARCH_DIRECTIVE)
+else
+march32-set-${ARM_CORTEX_A5} := -mcpu=cortex-a5
+march32-set-${ARM_CORTEX_A7} := -mcpu=cortex-a7
+march32-set-${ARM_CORTEX_A9} := -mcpu=cortex-a9
+march32-set-${ARM_CORTEX_A12} := -mcpu=cortex-a12
+march32-set-${ARM_CORTEX_A15} := -mcpu=cortex-a15
+march32-set-${ARM_CORTEX_A17} := -mcpu=cortex-a17
+march32-neon-$(ARM_WITH_NEON) := -mfpu=neon
+
+# default to -march=armv7-a as target directive
+march32-set-yes ?= -march=armv7-a
+march-directive := ${march32-set-yes} ${march32-neon-yes}
+endif
+
+# Platform may override these extension support directives:
+#
+# ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING
+# Defined if core supports the Large Page Addressing extension.
+#
+# ARMV7_SUPPORTS_VIRTUALIZATION
+# Defined if ARMv7 core supports the Virtualization extension.
+#
+# ARMV7_SUPPORTS_GENERIC_TIMER
+# Defined if ARMv7 core supports the Generic Timer extension.
+
+ifeq ($(filter yes,$(ARM_CORTEX_A7) $(ARM_CORTEX_A12) $(ARM_CORTEX_A15) $(ARM_CORTEX_A17)),yes)
+$(eval $(call add_defines,\
+ $(sort \
+ ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING \
+ ARMV7_SUPPORTS_VIRTUALIZATION \
+ ARMV7_SUPPORTS_GENERIC_TIMER \
+ ARMV7_SUPPORTS_VFP \
+)))
+endif
+
+ifeq ($(ARM_CORTEX_A5),yes)
+$(eval $(call add_define,ARM_CORTEX_A5))
+endif
diff --git a/make_helpers/build_env.mk b/make_helpers/build_env.mk
new file mode 100644
index 0000000..83093bd
--- /dev/null
+++ b/make_helpers/build_env.mk
@@ -0,0 +1,72 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# This file contains the logic to identify and include any relevant
+# build environment specific make include files.
+
+ifndef BUILD_ENV_MK
+ BUILD_ENV_MK := $(lastword $(MAKEFILE_LIST))
+
+ # Block possible built-in command definitions that are not fully portable.
+ # This traps occurences that need replacing with our OS portable macros
+ COPY := $$(error "Replace COPY with call to SHELL_COPY or SHELL_COPY_TREE.")
+ CP := $$(error "Replace CP with call to SHELL_COPY or SHELL_COPY_TREE.")
+ DEL := $$(error "Replace DEL with call to SHELL_DELETE.")
+ MD := $$(error "Replace MD with call to MAKE_PREREQ_DIR.")
+ MKDIR := $$(error "Replace MKDIR with call to MAKE_PREREQ_DIR.")
+ RD := $$(error "Replace RD with call to SHELL_REMOVE_DIR.")
+ RM := $$(error "Replace RM with call to SHELL_DELETE.")
+ RMDIR := $$(error "Replace RMDIR with call to SHELL_REMOVE_DIR.")
+
+ ENV_FILE_TO_INCLUDE := unix.mk
+ ifdef OSTYPE
+ ifneq ($(findstring ${OSTYPE}, cygwin),)
+ ENV_FILE_TO_INCLUDE := cygwin.mk
+ else
+ ifneq ($(findstring ${OSTYPE}, MINGW32 mingw msys),)
+ ENV_FILE_TO_INCLUDE := msys.mk
+ endif
+ endif
+ else
+ ifdef MSYSTEM
+ # Although the MINGW MSYS shell sets OSTYPE as msys in its environment,
+ # it does not appear in the GNU make view of environment variables.
+ # We use MSYSTEM as an alternative, as that is seen by make
+ ifneq ($(findstring ${MSYSTEM}, MINGW32 mingw msys),)
+ OSTYPE ?= msys
+ ENV_FILE_TO_INCLUDE := msys.mk
+ endif
+ else
+ ifdef OS
+ ifneq ($(findstring ${OS}, Windows_NT),)
+ ENV_FILE_TO_INCLUDE := windows.mk
+ endif
+ endif
+ endif
+ endif
+ include ${MAKE_HELPERS_DIRECTORY}${ENV_FILE_TO_INCLUDE}
+ ENV_FILE_TO_INCLUDE :=
+
+ ifndef SHELL_COPY
+ $(error "SHELL_COPY not defined for build environment.")
+ endif
+ ifndef SHELL_COPY_TREE
+ $(error "SHELL_COPY_TREE not defined for build environment.")
+ endif
+ ifndef SHELL_DELETE_ALL
+ $(error "SHELL_DELETE_ALL not defined for build environment.")
+ endif
+ ifndef SHELL_DELETE
+ $(error "SHELL_DELETE not defined for build environment.")
+ endif
+ ifndef MAKE_PREREQ_DIR
+ $(error "MAKE_PREREQ_DIR not defined for build environment.")
+ endif
+ ifndef SHELL_REMOVE_DIR
+ $(error "SHELL_REMOVE_DIR not defined for build environment.")
+ endif
+
+endif
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
new file mode 100644
index 0000000..71cf18b
--- /dev/null
+++ b/make_helpers/build_macros.mk
@@ -0,0 +1,683 @@
+#
+# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Report an error if the eval make function is not available.
+$(eval eval_available := T)
+ifneq (${eval_available},T)
+ $(error This makefile only works with a Make program that supports $$(eval))
+endif
+
+# Some utility macros for manipulating awkward (whitespace) characters.
+blank :=
+space :=${blank} ${blank}
+comma := ,
+
+# A user defined function to recursively search for a filename below a directory
+# $1 is the directory root of the recursive search (blank for current directory).
+# $2 is the file name to search for.
+define rwildcard
+$(strip $(foreach d,$(wildcard ${1}*),$(call rwildcard,${d}/,${2}) $(filter $(subst *,%,%${2}),${d})))
+endef
+
+# This table is used in converting lower case to upper case.
+uppercase_table:=a,A b,B c,C d,D e,E f,F g,G h,H i,I j,J k,K l,L m,M n,N o,O p,P q,Q r,R s,S t,T u,U v,V w,W x,X y,Y z,Z
+
+# Internal macro used for converting lower case to upper case.
+# $(1) = upper case table
+# $(2) = String to convert
+define uppercase_internal
+$(if $(1),$$(subst $(firstword $(1)),$(call uppercase_internal,$(wordlist 2,$(words $(1)),$(1)),$(2))),$(2))
+endef
+
+# A macro for converting a string to upper case
+# $(1) = String to convert
+define uppercase
+$(eval uppercase_result:=$(call uppercase_internal,$(uppercase_table),$(1)))$(uppercase_result)
+endef
+
+# Convenience function for setting a variable to 0 if not previously set
+# $(eval $(call default_zero,FOO))
+define default_zero
+ $(eval $(1) ?= 0)
+endef
+
+# Convenience function for setting a list of variables to 0 if not previously set
+# $(eval $(call default_zeros,FOO BAR))
+define default_zeros
+ $(foreach var,$1,$(eval $(call default_zero,$(var))))
+endef
+
+# Convenience function for adding build definitions
+# $(eval $(call add_define,FOO)) will have:
+# -DFOO if $(FOO) is empty; -DFOO=$(FOO) otherwise
+define add_define
+ DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
+endef
+
+# Convenience function for addding multiple build definitions
+# $(eval $(call add_defines,FOO BOO))
+define add_defines
+ $(foreach def,$1,$(eval $(call add_define,$(def))))
+endef
+
+# Convenience function for adding build definitions
+# $(eval $(call add_define_val,FOO,BAR)) will have:
+# -DFOO=BAR
+define add_define_val
+ DEFINES += -D$(1)=$(2)
+endef
+
+# Convenience function for verifying option has a boolean value
+# $(eval $(call assert_boolean,FOO)) will assert FOO is 0 or 1
+define assert_boolean
+ $(if $($(1)),,$(error $(1) must not be empty))
+ $(if $(filter-out 0 1,$($1)),$(error $1 must be boolean))
+endef
+
+# Convenience function for verifying options have boolean values
+# $(eval $(call assert_booleans,FOO BOO)) will assert FOO and BOO for 0 or 1 values
+define assert_booleans
+ $(foreach bool,$1,$(eval $(call assert_boolean,$(bool))))
+endef
+
+0-9 := 0 1 2 3 4 5 6 7 8 9
+
+# Function to verify that a given option $(1) contains a numeric value
+define assert_numeric
+$(if $($(1)),,$(error $(1) must not be empty))
+$(eval __numeric := $($(1)))
+$(foreach d,$(0-9),$(eval __numeric := $(subst $(d),,$(__numeric))))
+$(if $(__numeric),$(error $(1) must be numeric))
+endef
+
+# Convenience function for verifying options have numeric values
+# $(eval $(call assert_numerics,FOO BOO)) will assert FOO and BOO contain numeric values
+define assert_numerics
+ $(foreach num,$1,$(eval $(call assert_numeric,$(num))))
+endef
+
+# Convenience function to check for a given linker option. An call to
+# $(call ld_option, --no-XYZ) will return --no-XYZ if supported by the linker
+define ld_option
+ $(shell if $(LD) $(1) -v >/dev/null 2>&1; then echo $(1); fi )
+endef
+
+# Convenience function to check for a given compiler option. A call to
+# $(call cc_option, --no-XYZ) will return --no-XYZ if supported by the compiler
+define cc_option
+ $(shell if $(CC) $(1) -c -x c /dev/null -o /dev/null >/dev/null 2>&1; then echo $(1); fi )
+endef
+
+# CREATE_SEQ is a recursive function to create sequence of numbers from 1 to
+# $(2) and assign the sequence to $(1)
+define CREATE_SEQ
+$(if $(word $(2), $($(1))),\
+ $(eval $(1) += $(words $($(1))))\
+ $(eval $(1) := $(filter-out 0,$($(1)))),\
+ $(eval $(1) += $(words $($(1))))\
+ $(call CREATE_SEQ,$(1),$(2))\
+)
+endef
+
+# IMG_MAPFILE defines the output file describing the memory map corresponding
+# to a BL stage
+# $(1) = BL stage
+define IMG_MAPFILE
+ ${BUILD_DIR}/$(1).map
+endef
+
+# IMG_ELF defines the elf file corresponding to a BL stage
+# $(1) = BL stage
+define IMG_ELF
+ ${BUILD_DIR}/$(1).elf
+endef
+
+# IMG_DUMP defines the symbols dump file corresponding to a BL stage
+# $(1) = BL stage
+define IMG_DUMP
+ ${BUILD_DIR}/$(1).dump
+endef
+
+# IMG_BIN defines the default image file corresponding to a BL stage
+# $(1) = BL stage
+define IMG_BIN
+ ${BUILD_PLAT}/$(1).bin
+endef
+
+# IMG_ENC_BIN defines the default encrypted image file corresponding to a
+# BL stage
+# $(1) = BL stage
+define IMG_ENC_BIN
+ ${BUILD_PLAT}/$(1)_enc.bin
+endef
+
+# ENCRYPT_FW invokes enctool to encrypt firmware binary
+# $(1) = input firmware binary
+# $(2) = output encrypted firmware binary
+define ENCRYPT_FW
+$(2): $(1) enctool
+ $$(ECHO) " ENC $$<"
+ $$(Q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
+endef
+
+# TOOL_ADD_PAYLOAD appends the command line arguments required by fiptool to
+# package a new payload and/or by cert_create to generate certificate.
+# Optionally, it adds the dependency on this payload
+# $(1) = payload filename (i.e. bl31.bin)
+# $(2) = command line option for the specified payload (i.e. --soc-fw)
+# $(3) = tool target dependency (optional) (ex. build/fvp/release/bl31.bin)
+# $(4) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+# $(5) = encrypted payload (optional) (ex. build/fvp/release/bl31_enc.bin)
+define TOOL_ADD_PAYLOAD
+ifneq ($(5),)
+ $(4)FIP_ARGS += $(2) $(5)
+ $(if $(3),$(4)CRT_DEPS += $(1))
+else
+ $(4)FIP_ARGS += $(2) $(1)
+ $(if $(3),$(4)CRT_DEPS += $(3))
+endif
+ $(if $(3),$(4)FIP_DEPS += $(3))
+ $(4)CRT_ARGS += $(2) $(1)
+endef
+
+# TOOL_ADD_IMG_PAYLOAD works like TOOL_ADD_PAYLOAD, but applies image filters
+# before passing them to host tools if BL*_PRE_TOOL_FILTER is defined.
+# $(1) = image_type (scp_bl2, bl33, etc.)
+# $(2) = payload filepath (ex. build/fvp/release/bl31.bin)
+# $(3) = command line option for the specified payload (ex. --soc-fw)
+# $(4) = tool target dependency (optional) (ex. build/fvp/release/bl31.bin)
+# $(5) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+# $(6) = encrypted payload (optional) (ex. build/fvp/release/bl31_enc.bin)
+
+define TOOL_ADD_IMG_PAYLOAD
+
+$(eval PRE_TOOL_FILTER := $($(call uppercase,$(1))_PRE_TOOL_FILTER))
+
+ifneq ($(PRE_TOOL_FILTER),)
+
+$(eval PROCESSED_PATH := $(BUILD_PLAT)/$(1).bin$($(PRE_TOOL_FILTER)_SUFFIX))
+
+$(call $(PRE_TOOL_FILTER)_RULE,$(PROCESSED_PATH),$(2))
+
+$(PROCESSED_PATH): $(4)
+
+$(call TOOL_ADD_PAYLOAD,$(PROCESSED_PATH),$(3),$(PROCESSED_PATH),$(5),$(6))
+
+else
+$(call TOOL_ADD_PAYLOAD,$(2),$(3),$(4),$(5),$(6))
+endif
+endef
+
+# CERT_ADD_CMD_OPT adds a new command line option to the cert_create invocation
+# $(1) = parameter filename
+# $(2) = cert_create command line option for the specified parameter
+# $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+define CERT_ADD_CMD_OPT
+ $(3)CRT_ARGS += $(2) $(1)
+endef
+
+# TOOL_ADD_IMG allows the platform to specify an external image to be packed
+# in the FIP and/or for which certificate is generated. It also adds a
+# dependency on the image file, aborting the build if the file does not exist.
+# $(1) = image_type (scp_bl2, bl33, etc.)
+# $(2) = command line option for fiptool (--scp-fw, --nt-fw, etc)
+# $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+# $(4) = Image encryption flag (optional) (0, 1)
+# Example:
+# $(eval $(call TOOL_ADD_IMG,bl33,--nt-fw))
+define TOOL_ADD_IMG
+ # Build option to specify the image filename (SCP_BL2, BL33, etc)
+ # This is the uppercase form of the first parameter
+ $(eval _V := $(call uppercase,$(1)))
+
+ # $(check_$(1)_cmd) variable is executed in the check_$(1) target and also
+ # is put into the ${CHECK_$(3)FIP_CMD} variable which is executed by the
+ # target ${BUILD_PLAT}/${$(3)FIP_NAME}.
+ $(eval check_$(1)_cmd := \
+ $(if $(value $(_V)),,$$$$(error "Platform '${PLAT}' requires $(_V). Please set $(_V) to point to the right file")) \
+ $(if $(wildcard $(value $(_V))),,$$$$(error '$(_V)=$(value $(_V))' was specified, but '$(value $(_V))' does not exist)) \
+ )
+
+ $(3)CRT_DEPS += check_$(1)
+ CHECK_$(3)FIP_CMD += $$(check_$(1)_cmd)
+ifeq ($(4),1)
+ $(eval ENC_BIN := ${BUILD_PLAT}/$(1)_enc.bin)
+ $(call ENCRYPT_FW,$(value $(_V)),$(ENC_BIN))
+ $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(ENC_BIN),$(3), \
+ $(ENC_BIN))
+else
+ $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(if $(wildcard $(value $(_V))),$(value $(_V)),FORCE),$(3))
+endif
+
+.PHONY: check_$(1)
+check_$(1):
+ $(check_$(1)_cmd)
+endef
+
+# SELECT_OPENSSL_API_VERSION selects the OpenSSL API version to be used to
+# build the host tools by checking the version of OpenSSL located under
+# the path defined by the OPENSSL_DIR variable. It receives no parameters.
+define SELECT_OPENSSL_API_VERSION
+ # Set default value for USING_OPENSSL3 macro to 0
+ $(eval USING_OPENSSL3 = 0)
+ # Obtain the OpenSSL version for the build located under OPENSSL_DIR
+ $(eval OPENSSL_INFO := $(shell LD_LIBRARY_PATH=${OPENSSL_DIR}:${OPENSSL_DIR}/lib ${OPENSSL_BIN_PATH}/openssl version))
+ $(eval OPENSSL_CURRENT_VER = $(word 2, ${OPENSSL_INFO}))
+ $(eval OPENSSL_CURRENT_VER_MAJOR = $(firstword $(subst ., ,$(OPENSSL_CURRENT_VER))))
+ # If OpenSSL version is 3.x, then set USING_OPENSSL3 flag to 1
+ $(if $(filter 3,$(OPENSSL_CURRENT_VER_MAJOR)), $(eval USING_OPENSSL3 = 1))
+endef
+
+################################################################################
+# Generic image processing filters
+################################################################################
+
+# GZIP
+define GZIP_RULE
+$(1): $(2)
+ $(ECHO) " GZIP $$@"
+ $(Q)gzip -n -f -9 $$< --stdout > $$@
+endef
+
+GZIP_SUFFIX := .gz
+
+################################################################################
+# Auxiliary macros to build TF images from sources
+################################################################################
+
+MAKE_DEP = -Wp,-MD,$(DEP) -MT $$@ -MP
+
+
+# MAKE_C_LIB builds a C source file and generates the dependency file
+# $(1) = output directory
+# $(2) = source file (%.c)
+# $(3) = library name
+define MAKE_C_LIB
+$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
+$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
+$(eval LIB := $(call uppercase, $(notdir $(1))))
+
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
+ $$(ECHO) " CC $$<"
+ $$(Q)$$(CC) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+
+-include $(DEP)
+
+endef
+
+# MAKE_S_LIB builds an assembly source file and generates the dependency file
+# $(1) = output directory
+# $(2) = source file (%.S)
+# $(3) = library name
+define MAKE_S_LIB
+$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
+$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
+
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
+ $$(ECHO) " AS $$<"
+ $$(Q)$$(AS) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+
+-include $(DEP)
+
+endef
+
+
+# MAKE_C builds a C source file and generates the dependency file
+# $(1) = output directory
+# $(2) = source file (%.c)
+# $(3) = BL stage
+define MAKE_C
+
+$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
+$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
+
+$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+$(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS) $(PLAT_BL_COMMON_CFLAGS))
+
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
+ $$(ECHO) " CC $$<"
+ $$(Q)$$(CC) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+
+-include $(DEP)
+
+endef
+
+
+# MAKE_S builds an assembly source file and generates the dependency file
+# $(1) = output directory
+# $(2) = assembly file (%.S)
+# $(3) = BL stage
+define MAKE_S
+
+$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
+$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
+
+$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+$(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS) $(PLAT_BL_COMMON_ASFLAGS))
+
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
+ $$(ECHO) " AS $$<"
+ $$(Q)$$(AS) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+
+-include $(DEP)
+
+endef
+
+
+# MAKE_LD generate the linker script using the C preprocessor
+# $(1) = output linker script
+# $(2) = input template
+# $(3) = BL stage
+define MAKE_LD
+
+$(eval DEP := $(1).d)
+
+$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+
+$(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
+ $$(ECHO) " PP $$<"
+ $$(Q)$$(CPP) $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$<
+
+-include $(DEP)
+
+endef
+
+# MAKE_LIB_OBJS builds both C and assembly source files
+# $(1) = output directory
+# $(2) = list of source files
+# $(3) = name of the library
+define MAKE_LIB_OBJS
+ $(eval C_OBJS := $(filter %.c,$(2)))
+ $(eval REMAIN := $(filter-out %.c,$(2)))
+ $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C_LIB,$(1),$(obj),$(3))))
+
+ $(eval S_OBJS := $(filter %.S,$(REMAIN)))
+ $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
+ $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S_LIB,$(1),$(obj),$(3))))
+
+ $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
+endef
+
+
+# MAKE_OBJS builds both C and assembly source files
+# $(1) = output directory
+# $(2) = list of source files (both C and assembly)
+# $(3) = BL stage
+define MAKE_OBJS
+ $(eval C_OBJS := $(filter %.c,$(2)))
+ $(eval REMAIN := $(filter-out %.c,$(2)))
+ $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj),$(3))))
+
+ $(eval S_OBJS := $(filter %.S,$(REMAIN)))
+ $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
+ $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3))))
+
+ $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
+endef
+
+
+# NOTE: The line continuation '\' is required in the next define otherwise we
+# end up with a line-feed characer at the end of the last c filename.
+# Also bear this issue in mind if extending the list of supported filetypes.
+define SOURCES_TO_OBJS
+ $(notdir $(patsubst %.c,%.o,$(filter %.c,$(1)))) \
+ $(notdir $(patsubst %.S,%.o,$(filter %.S,$(1))))
+endef
+
+# Allow overriding the timestamp, for example for reproducible builds, or to
+# synchronize timestamps across multiple projects.
+# This must be set to a C string (including quotes where applicable).
+BUILD_MESSAGE_TIMESTAMP ?= __TIME__", "__DATE__
+
+.PHONY: libraries
+
+# MAKE_LIB_DIRS macro defines the target for the directory where
+# libraries are created
+define MAKE_LIB_DIRS
+ $(eval LIB_DIR := ${BUILD_PLAT}/lib)
+ $(eval ROMLIB_DIR := ${BUILD_PLAT}/romlib)
+ $(eval LIBWRAPPER_DIR := ${BUILD_PLAT}/libwrapper)
+ $(eval $(call MAKE_PREREQ_DIR,${LIB_DIR},${BUILD_PLAT}))
+ $(eval $(call MAKE_PREREQ_DIR,${ROMLIB_DIR},${BUILD_PLAT}))
+ $(eval $(call MAKE_PREREQ_DIR,${LIBWRAPPER_DIR},${BUILD_PLAT}))
+endef
+
+# MAKE_LIB macro defines the targets and options to build each BL image.
+# Arguments:
+# $(1) = Library name
+define MAKE_LIB
+ $(eval BUILD_DIR := ${BUILD_PLAT}/lib$(1))
+ $(eval LIB_DIR := ${BUILD_PLAT}/lib)
+ $(eval ROMLIB_DIR := ${BUILD_PLAT}/romlib)
+ $(eval SOURCES := $(LIB$(call uppercase,$(1))_SRCS))
+ $(eval OBJS := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
+
+$(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
+$(eval $(call MAKE_LIB_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+
+.PHONY : lib${1}_dirs
+lib${1}_dirs: | ${BUILD_DIR} ${LIB_DIR} ${ROMLIB_DIR} ${LIBWRAPPER_DIR}
+libraries: ${LIB_DIR}/lib$(1).a
+ifneq ($(findstring armlink,$(notdir $(LD))),)
+LDPATHS = --userlibpath=${LIB_DIR}
+LDLIBS += --library=$(1)
+else
+LDPATHS = -L${LIB_DIR}
+LDLIBS += -l$(1)
+endif
+
+ifeq ($(USE_ROMLIB),1)
+LIBWRAPPER = -lwrappers
+endif
+
+all: ${LIB_DIR}/lib$(1).a
+
+${LIB_DIR}/lib$(1).a: $(OBJS)
+ $$(ECHO) " AR $$@"
+ $$(Q)$$(AR) cr $$@ $$?
+endef
+
+# Generate the path to one or more preprocessed linker scripts given the paths
+# of their sources.
+#
+# Arguments:
+# $(1) = path to one or more linker script sources
+define linker_script_path
+ $(patsubst %.S,$(BUILD_DIR)/%,$(1))
+endef
+
+# MAKE_BL macro defines the targets and options to build each BL image.
+# Arguments:
+# $(1) = BL stage
+# $(2) = FIP command line option (if empty, image will not be included in the FIP)
+# $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+# $(4) = BL encryption flag (optional) (0, 1)
+define MAKE_BL
+ $(eval BUILD_DIR := ${BUILD_PLAT}/$(1))
+ $(eval BL_SOURCES := $($(call uppercase,$(1))_SOURCES))
+ $(eval SOURCES := $(sort $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES)))
+ $(eval OBJS := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
+ $(eval MAPFILE := $(call IMG_MAPFILE,$(1)))
+ $(eval ELF := $(call IMG_ELF,$(1)))
+ $(eval DUMP := $(call IMG_DUMP,$(1)))
+ $(eval BIN := $(call IMG_BIN,$(1)))
+ $(eval ENC_BIN := $(call IMG_ENC_BIN,$(1)))
+ $(eval BL_LIBS := $($(call uppercase,$(1))_LIBS))
+
+ $(eval DEFAULT_LINKER_SCRIPT_SOURCE := $($(call uppercase,$(1))_DEFAULT_LINKER_SCRIPT_SOURCE))
+ $(eval DEFAULT_LINKER_SCRIPT := $(call linker_script_path,$(DEFAULT_LINKER_SCRIPT_SOURCE)))
+
+ $(eval LINKER_SCRIPT_SOURCES := $($(call uppercase,$(1))_LINKER_SCRIPT_SOURCES))
+ $(eval LINKER_SCRIPTS := $(call linker_script_path,$(LINKER_SCRIPT_SOURCES)))
+
+ # We use sort only to get a list of unique object directory names.
+ # ordering is not relevant but sort removes duplicates.
+ $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS} ${DEFAULT_LINKER_SCRIPT} ${LINKER_SCRIPTS})))
+ # The $(dir ) function leaves a trailing / on the directory names
+ # Rip off the / to match directory names with make rule targets.
+ $(eval OBJ_DIRS := $(patsubst %/,%,$(TEMP_OBJ_DIRS)))
+
+# Create generators for object directory structure
+
+$(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
+
+$(eval $(foreach objd,${OBJ_DIRS},
+ $(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
+
+.PHONY : ${1}_dirs
+
+# We use order-only prerequisites to ensure that directories are created,
+# but do not cause re-builds every time a file is written.
+${1}_dirs: | ${OBJ_DIRS}
+
+$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+
+# Generate targets to preprocess each required linker script
+$(eval $(foreach source,$(DEFAULT_LINKER_SCRIPT_SOURCE) $(LINKER_SCRIPT_SOURCES), \
+ $(call MAKE_LD,$(call linker_script_path,$(source)),$(source),$(1))))
+
+$(eval BL_LDFLAGS := $($(call uppercase,$(1))_LDFLAGS))
+
+ifeq ($(USE_ROMLIB),1)
+$(ELF): romlib.bin
+endif
+
+# MODULE_OBJS can be assigned by vendors with different compiled
+# object file path, and prebuilt object file path.
+$(eval OBJS += $(MODULE_OBJS))
+
+$(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $(1)_dirs libraries $(BL_LIBS)
+ $$(ECHO) " LD $$@"
+ifdef MAKE_BUILD_STRINGS
+ $(call MAKE_BUILD_STRINGS,$(BUILD_DIR)/build_message.o)
+else
+ @echo 'const char build_message[] = "Built : "$(BUILD_MESSAGE_TIMESTAMP); \
+ const char version_string[] = "${VERSION_STRING}"; \
+ const char version[] = "${VERSION}";' | \
+ $$(CC) $$(TF_CFLAGS) $$(CFLAGS) -xc -c - -o $(BUILD_DIR)/build_message.o
+endif
+ifneq ($(findstring armlink,$(notdir $(LD))),)
+ $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
+ --predefine="-D__LINKER__=$(__LINKER__)" \
+ --predefine="-DTF_CFLAGS=$(TF_CFLAGS)" \
+ --map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/${1}.scat \
+ $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \
+ $(BUILD_DIR)/build_message.o $(OBJS)
+else ifneq ($(findstring gcc,$(notdir $(LD))),)
+ $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \
+ $(addprefix -Wl$(comma)--script$(comma),$(LINKER_SCRIPTS)) -Wl,--script,$(DEFAULT_LINKER_SCRIPT) \
+ $(BUILD_DIR)/build_message.o \
+ $(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
+else
+ $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
+ $(addprefix -T ,$(LINKER_SCRIPTS)) --script $(DEFAULT_LINKER_SCRIPT) \
+ $(BUILD_DIR)/build_message.o \
+ $(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
+endif
+ifeq ($(DISABLE_BIN_GENERATION),1)
+ @${ECHO_BLANK_LINE}
+ @echo "Built $$@ successfully"
+ @${ECHO_BLANK_LINE}
+endif
+
+$(DUMP): $(ELF)
+ $${ECHO} " OD $$@"
+ $${Q}$${OD} -dx $$< > $$@
+
+$(BIN): $(ELF)
+ $${ECHO} " BIN $$@"
+ $$(Q)$$(OC) -O binary $$< $$@
+ @${ECHO_BLANK_LINE}
+ @echo "Built $$@ successfully"
+ @${ECHO_BLANK_LINE}
+
+.PHONY: $(1)
+ifeq ($(DISABLE_BIN_GENERATION),1)
+$(1): $(ELF) $(DUMP)
+else
+$(1): $(BIN) $(DUMP)
+endif
+
+all: $(1)
+
+ifeq ($(4),1)
+$(call ENCRYPT_FW,$(BIN),$(ENC_BIN))
+$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(BIN),--$(2),$(ENC_BIN),$(3), \
+ $(ENC_BIN)))
+else
+$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(BIN),--$(2),$(BIN),$(3)))
+endif
+
+endef
+
+# Convert device tree source file names to matching blobs
+# $(1) = input dts
+define SOURCES_TO_DTBS
+ $(notdir $(patsubst %.dts,%.dtb,$(filter %.dts,$(1))))
+endef
+
+# MAKE_FDT_DIRS macro creates the prerequisite directories that host the
+# FDT binaries
+# $(1) = output directory
+# $(2) = input dts
+define MAKE_FDT_DIRS
+ $(eval DTBS := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
+ $(eval TEMP_DTB_DIRS := $(sort $(dir ${DTBS})))
+ # The $(dir ) function leaves a trailing / on the directory names
+ # Rip off the / to match directory names with make rule targets.
+ $(eval DTB_DIRS := $(patsubst %/,%,$(TEMP_DTB_DIRS)))
+
+$(eval $(foreach objd,${DTB_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
+
+fdt_dirs: ${DTB_DIRS}
+endef
+
+# MAKE_DTB generate the Flattened device tree binary
+# $(1) = output directory
+# $(2) = input dts
+define MAKE_DTB
+
+# List of DTB file(s) to generate, based on DTS file basename list
+$(eval DOBJ := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
+# List of the pre-compiled DTS file(s)
+$(eval DPRE := $(addprefix $(1)/,$(patsubst %.dts,%.pre.dts,$(notdir $(2)))))
+# Dependencies of the pre-compiled DTS file(s) on its source and included files
+$(eval DTSDEP := $(patsubst %.dtb,%.o.d,$(DOBJ)))
+# Dependencies of the DT compilation on its pre-compiled DTS
+$(eval DTBDEP := $(patsubst %.dtb,%.d,$(DOBJ)))
+
+$(DOBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
+ $${ECHO} " CPP $$<"
+ $(eval DTBS := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
+ $$(Q)$$(PP) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
+ $${ECHO} " DTC $$<"
+ $$(Q)$$(DTC) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $(DPRE)
+
+-include $(DTBDEP)
+-include $(DTSDEP)
+
+endef
+
+# MAKE_DTBS builds flattened device tree sources
+# $(1) = output directory
+# $(2) = list of flattened device tree source files
+define MAKE_DTBS
+ $(eval DOBJS := $(filter %.dts,$(2)))
+ $(eval REMAIN := $(filter-out %.dts,$(2)))
+ $(and $(REMAIN),$(error FDT_SOURCES contain non-DTS files: $(REMAIN)))
+ $(eval $(foreach obj,$(DOBJS),$(call MAKE_DTB,$(1),$(obj))))
+
+ $(eval $(call MAKE_FDT_DIRS,$(1),$(2)))
+
+dtbs: $(DTBS)
+all: dtbs
+endef
diff --git a/make_helpers/cygwin.mk b/make_helpers/cygwin.mk
new file mode 100644
index 0000000..04a963f
--- /dev/null
+++ b/make_helpers/cygwin.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+# OS specific definitions for builds in a Cygwin environment.
+# Cygwin allows us to use unix style commands on a windows platform.
+
+ifndef CYGWIN_MK
+ CYGWIN_MK := $(lastword $(MAKEFILE_LIST))
+
+ include ${MAKE_HELPERS_DIRECTORY}unix.mk
+
+ # In cygwin executable files have the Windows .exe extension type.
+ BIN_EXT := .exe
+
+endif
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
new file mode 100644
index 0000000..f0f157c
--- /dev/null
+++ b/make_helpers/defaults.mk
@@ -0,0 +1,375 @@
+#
+# Copyright (c) 2016-2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Default, static values for build variables, listed in alphabetic order.
+# Dependencies between build options, if any, are handled in the top-level
+# Makefile, after this file is included. This ensures that the former is better
+# poised to handle dependencies, as all build variables would have a default
+# value by then.
+
+# Use T32 by default
+AARCH32_INSTRUCTION_SET := T32
+
+# The AArch32 Secure Payload to be built as BL32 image
+AARCH32_SP := none
+
+# The Target build architecture. Supported values are: aarch64, aarch32.
+ARCH := aarch64
+
+# ARM Architecture feature modifiers: none by default
+ARM_ARCH_FEATURE := none
+
+# ARM Architecture major and minor versions: 8.0 by default.
+ARM_ARCH_MAJOR := 8
+ARM_ARCH_MINOR := 0
+
+# Base commit to perform code check on
+BASE_COMMIT := origin/master
+
+# Execute BL2 at EL3
+RESET_TO_BL2 := 0
+
+# Only use SP packages if SP layout JSON is defined
+BL2_ENABLE_SP_LOAD := 0
+
+# BL2 image is stored in XIP memory, for now, this option is only supported
+# when RESET_TO_BL2 is 1.
+BL2_IN_XIP_MEM := 0
+
+# Do dcache invalidate upon BL2 entry at EL3
+BL2_INV_DCACHE := 1
+
+# Select the branch protection features to use.
+BRANCH_PROTECTION := 0
+
+# By default, consider that the platform may release several CPUs out of reset.
+# The platform Makefile is free to override this value.
+COLD_BOOT_SINGLE_CPU := 0
+
+# Flag to compile in coreboot support code. Exclude by default. The coreboot
+# Makefile system will set this when compiling TF as part of a coreboot image.
+COREBOOT := 0
+
+# For Chain of Trust
+CREATE_KEYS := 1
+
+# Build flag to include AArch32 registers in cpu context save and restore during
+# world switch. This flag must be set to 0 for AArch64-only platforms.
+CTX_INCLUDE_AARCH32_REGS := 1
+
+# Include FP registers in cpu context
+CTX_INCLUDE_FPREGS := 0
+
+# Debug build
+DEBUG := 0
+
+# By default disable authenticated decryption support.
+DECRYPTION_SUPPORT := none
+
+# Build platform
+DEFAULT_PLAT := fvp
+
+# Disable the generation of the binary image (ELF only).
+DISABLE_BIN_GENERATION := 0
+
+# Enable capability to disable authentication dynamically. Only meant for
+# development platforms.
+DYN_DISABLE_AUTH := 0
+
+# Enable the Maximum Power Mitigation Mechanism on supporting cores.
+ENABLE_MPMM := 0
+
+# Enable MPMM configuration via FCONF.
+ENABLE_MPMM_FCONF := 0
+
+# Flag to Enable Position Independant support (PIE)
+ENABLE_PIE := 0
+
+# Flag to enable Performance Measurement Framework
+ENABLE_PMF := 0
+
+# Flag to enable PSCI STATs functionality
+ENABLE_PSCI_STAT := 0
+
+# Flag to enable runtime instrumentation using PMF
+ENABLE_RUNTIME_INSTRUMENTATION := 0
+
+# Flag to enable stack corruption protection
+ENABLE_STACK_PROTECTOR := 0
+
+# Flag to enable exception handling in EL3
+EL3_EXCEPTION_HANDLING := 0
+
+# By default BL31 encryption disabled
+ENCRYPT_BL31 := 0
+
+# By default BL32 encryption disabled
+ENCRYPT_BL32 := 0
+
+# Default dummy firmware encryption key
+ENC_KEY := 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
+
+# Default dummy nonce for firmware encryption
+ENC_NONCE := 1234567890abcdef12345678
+
+# Build flag to treat usage of deprecated platform and framework APIs as error.
+ERROR_DEPRECATED := 0
+
+# Fault injection support
+FAULT_INJECTION_SUPPORT := 0
+
+# Flag to enable architectural features detection mechanism
+FEATURE_DETECTION := 0
+
+# Byte alignment that each component in FIP is aligned to
+FIP_ALIGN := 0
+
+# Default FIP file name
+FIP_NAME := fip.bin
+
+# Default FWU_FIP file name
+FWU_FIP_NAME := fwu_fip.bin
+
+# By default firmware encryption with SSK
+FW_ENC_STATUS := 0
+
+# For Chain of Trust
+GENERATE_COT := 0
+
+# Hint platform interrupt control layer that Group 0 interrupts are for EL3. By
+# default, they are for Secure EL1.
+GICV2_G0_FOR_EL3 := 0
+
+# Route NS External Aborts to EL3. Disabled by default; External Aborts are handled
+# by lower ELs.
+HANDLE_EA_EL3_FIRST_NS := 0
+
+# Enable Handoff protocol using transfer lists
+TRANSFER_LIST := 0
+
+# Secure hash algorithm flag, accepts 3 values: sha256, sha384 and sha512.
+# The default value is sha256.
+HASH_ALG := sha256
+
+# Whether system coherency is managed in hardware, without explicit software
+# operations.
+HW_ASSISTED_COHERENCY := 0
+
+# Flag to enable trapping of implementation defined sytem registers
+IMPDEF_SYSREG_TRAP := 0
+
+# Set the default algorithm for the generation of Trusted Board Boot keys
+KEY_ALG := rsa
+
+# Set the default key size in case KEY_ALG is rsa
+ifeq ($(KEY_ALG),rsa)
+KEY_SIZE := 2048
+endif
+
+# Option to build TF with Measured Boot support
+MEASURED_BOOT := 0
+
+# NS timer register save and restore
+NS_TIMER_SWITCH := 0
+
+# Include lib/libc in the final image
+OVERRIDE_LIBC := 0
+
+# Build PL011 UART driver in minimal generic UART mode
+PL011_GENERIC_UART := 0
+
+# By default, consider that the platform's reset address is not programmable.
+# The platform Makefile is free to override this value.
+PROGRAMMABLE_RESET_ADDRESS := 0
+
+# Flag used to choose the power state format: Extended State-ID or Original
+PSCI_EXTENDED_STATE_ID := 0
+
+# Enable PSCI OS-initiated mode support
+PSCI_OS_INIT_MODE := 0
+
+# By default, BL1 acts as the reset handler, not BL31
+RESET_TO_BL31 := 0
+
+# For Chain of Trust
+SAVE_KEYS := 0
+
+# Software Delegated Exception support
+SDEI_SUPPORT := 0
+
+# True Random Number firmware Interface support
+TRNG_SUPPORT := 0
+
+# Check to see if Errata ABI is supported
+ERRATA_ABI_SUPPORT := 0
+
+# Check to enable Errata ABI for platforms with non-arm interconnect
+ERRATA_NON_ARM_INTERCONNECT := 0
+
+# SMCCC PCI support
+SMC_PCI_SUPPORT := 0
+
+# Whether code and read-only data should be put on separate memory pages. The
+# platform Makefile is free to override this value.
+SEPARATE_CODE_AND_RODATA := 0
+
+# Put NOBITS sections (.bss, stacks, page tables, and coherent memory) in a
+# separate memory region, which may be discontiguous from the rest of BL31.
+SEPARATE_NOBITS_REGION := 0
+
+# Put BL2 NOLOAD sections (.bss, stacks, page tables) in a separate memory
+# region, platform Makefile is free to override this value.
+SEPARATE_BL2_NOLOAD_REGION := 0
+
+# If the BL31 image initialisation code is recalimed after use for the secondary
+# cores stack
+RECLAIM_INIT_CODE := 0
+
+# SPD choice
+SPD := none
+
+# Enable the Management Mode (MM)-based Secure Partition Manager implementation
+SPM_MM := 0
+
+# Use the FF-A SPMC implementation in EL3.
+SPMC_AT_EL3 := 0
+
+# Enable SEL0 SP when SPMC is enabled at EL3
+SPMC_AT_EL3_SEL0_SP :=0
+
+# Use SPM at S-EL2 as a default config for SPMD
+SPMD_SPM_AT_SEL2 := 1
+
+# Flag to introduce an infinite loop in BL1 just before it exits into the next
+# image. This is meant to help debugging the post-BL2 phase.
+SPIN_ON_BL1_EXIT := 0
+
+# Flags to build TF with Trusted Boot support
+TRUSTED_BOARD_BOOT := 0
+
+# Build option to choose whether Trusted Firmware uses Coherent memory or not.
+USE_COHERENT_MEM := 1
+
+# Build option to add debugfs support
+USE_DEBUGFS := 0
+
+# Build option to fconf based io
+ARM_IO_IN_DTB := 0
+
+# Build option to support SDEI through fconf
+SDEI_IN_FCONF := 0
+
+# Build option to support Secure Interrupt descriptors through fconf
+SEC_INT_DESC_IN_FCONF := 0
+
+# Build option to choose whether Trusted Firmware uses library at ROM
+USE_ROMLIB := 0
+
+# Build option to choose whether the xlat tables of BL images can be read-only.
+# Note that this only serves as a higher level option to PLAT_RO_XLAT_TABLES,
+# which is the per BL-image option that actually enables the read-only tables
+# API. The reason for having this additional option is to have a common high
+# level makefile where we can check for incompatible features/build options.
+ALLOW_RO_XLAT_TABLES := 0
+
+# Chain of trust.
+COT := tbbr
+
+# Use tbbr_oid.h instead of platform_oid.h
+USE_TBBR_DEFS := 1
+
+# Build verbosity
+V := 0
+
+# Whether to enable D-Cache early during warm boot. This is usually
+# applicable for platforms wherein interconnect programming is not
+# required to enable cache coherency after warm reset (eg: single cluster
+# platforms).
+WARMBOOT_ENABLE_DCACHE_EARLY := 0
+
+# Default SVE vector length to maximum architected value
+SVE_VECTOR_LEN := 2048
+
+SANITIZE_UB := off
+
+# For ARMv8.1 (AArch64) platforms, enabling this option selects the spinlock
+# implementation variant using the ARMv8.1-LSE compare-and-swap instruction.
+# Default: disabled
+USE_SPINLOCK_CAS := 0
+
+# Enable Link Time Optimization
+ENABLE_LTO := 0
+
+# This option will include EL2 registers in cpu context save and restore during
+# EL2 firmware entry/exit. Internal flag not meant for direct setting.
+# Use SPD=spmd and SPMD_SPM_AT_SEL2=1 or ENABLE_RME=1 to enable
+# CTX_INCLUDE_EL2_REGS.
+CTX_INCLUDE_EL2_REGS := 0
+
+# Enable Memory tag extension which is supported for architecture greater
+# than Armv8.5-A
+# By default it is set to "no"
+SUPPORT_STACK_MEMTAG := no
+
+# Select workaround for AT speculative behaviour.
+ERRATA_SPECULATIVE_AT := 0
+
+# Trap RAS error record access from Non secure
+RAS_TRAP_NS_ERR_REC_ACCESS := 0
+
+# Build option to create cot descriptors using fconf
+COT_DESC_IN_DTB := 0
+
+# Build option to provide OpenSSL directory path
+OPENSSL_DIR := /usr
+
+# Select the openssl binary provided in OPENSSL_DIR variable
+ifeq ("$(wildcard ${OPENSSL_DIR}/bin)", "")
+ OPENSSL_BIN_PATH = ${OPENSSL_DIR}/apps
+else
+ OPENSSL_BIN_PATH = ${OPENSSL_DIR}/bin
+endif
+
+# Build option to use the SP804 timer instead of the generic one
+USE_SP804_TIMER := 0
+
+# Build option to define number of firmware banks, used in firmware update
+# metadata structure.
+NR_OF_FW_BANKS := 2
+
+# Build option to define number of images in firmware bank, used in firmware
+# update metadata structure.
+NR_OF_IMAGES_IN_FW_BANK := 1
+
+# Disable Firmware update support by default
+PSA_FWU_SUPPORT := 0
+
+# By default, disable the mocking of RSS provided services
+PLAT_RSS_NOT_SUPPORTED := 0
+
+# Dynamic Root of Trust for Measurement support
+DRTM_SUPPORT := 0
+
+# Check platform if cache management operations should be performed.
+# Disabled by default.
+CONDITIONAL_CMO := 0
+
+# By default, disable SPMD Logical partitions
+ENABLE_SPMD_LP := 0
+
+# By default, disable PSA crypto (use MbedTLS legacy crypto API).
+PSA_CRYPTO := 0
+
+# getc() support from the console(s).
+# Disabled by default because it constitutes an attack vector into TF-A. It
+# should only be enabled if there is a use case for it.
+ENABLE_CONSOLE_GETC := 0
+
+# Build option to disable EL2 when it is not used.
+# Most platforms switch from EL3 to NS-EL2 and hence the unused NS-EL2
+# functions must be enabled by platforms if they require it.
+# Disabled by default.
+INIT_UNUSED_NS_EL2 := 0
diff --git a/make_helpers/march.mk b/make_helpers/march.mk
new file mode 100644
index 0000000..2417709
--- /dev/null
+++ b/make_helpers/march.mk
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# This build helper makefile is used to determine a suitable march build
+# option to be used, based on platform provided ARM_ARCH_MAJOR/MINOR
+# data and compiler supported march version.
+
+# Set the compiler's target architecture profile based on
+# ARM_ARCH_MAJOR and ARM_ARCH_MINOR options.
+
+
+# This is used to collect available march values from compiler.
+# Example on a gcc-12.2 arm64 toolchain it will look like:
+# [...]
+#./aarch64-none-elf-gcc --target-help -march=foo
+# cc1: error: unknown value 'foo' for '-march'
+# cc1: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a armv8.5-a
+# armv8.6-a armv8.7-a armv8.8-a armv8-r armv9-a
+# [...]
+#
+GCC_MARCH_OUTPUT := $(shell $(CC) -march=foo -Q --help=target -v 2>&1)
+
+# This function is used to find the best march value supported by the given compiler.
+# We try to use `GCC_MARCH_OUTPUT` which has verbose message with supported march values we filter that
+# to find armvX.Y-a or armvX-a values, then filter the best supported arch based on ARM_ARCH_MAJOR.
+#
+# Example on a gcc-12.2 arm64 toolchain this will return armv9-a if platform requested for armv9.2-a
+# Similarly on gcc 11.3 it would return armv8.6-a if platform requested armv8.8-a
+define major_best_avail_march
+$(1) := $(lastword $(filter armv$(ARM_ARCH_MAJOR)% ,$(filter armv%-a, $(GCC_MARCH_OUTPUT))))
+endef
+
+# This function is used to just return latest march value supported by the given compiler.
+#
+# Example: this would return armv8.6-a on a gcc-11.3 when platform requested for armv9.0-a
+#
+# Thus this function should be used in conjunction with major_best_avail_march, when best match
+# is not found it should be ok to try with lastest known supported march value from the
+# compiler.
+define latest_match_march
+$(1) := $(lastword $(filter armv%-a, $(GCC_MARCH_OUTPUT)))
+endef
+
+ifdef MARCH_DIRECTIVE
+ march-directive := $(MARCH_DIRECTIVE)
+else
+
+ifeq (${ARM_ARCH_MINOR},0)
+ provided-march = armv${ARM_ARCH_MAJOR}-a
+else
+ provided-march = armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
+endif
+
+ifeq ($(findstring clang,$(notdir $(CC))),)
+
+# We expect from Platform to provide a correct Major/Minor value but expecting something
+# from compiler with unsupported march means we shouldn't fail without trying anything,
+# so here we try to find best supported march value and use that for compilation.
+# If we don't support current march version from gcc compiler, try with lower arch based on
+# availability. In TF-A there is no hard rule for need of higher version march for basic
+# functionality, denying a build on only this fact doesn't look correct, so try with best
+# or latest march values from whats available from compiler.
+ifeq (,$(findstring $(provided-march), $(GCC_MARCH_OUTPUT)))
+ $(eval $(call major_best_avail_march, available-march))
+
+ifeq (, $(available-march))
+ $(eval $(call latest_match_march, available-march))
+endif
+
+# If we fail to come up with any available-march value so far, don't update
+# provided-march and thus allow the build to fail using the provided-march
+# which is derived based on arch_major and arch_minor values.
+ifneq (,$(available-march))
+ provided-march := ${available-march}
+endif
+
+endif # provided-march supported
+endif # not clang
+
+march-directive := -march=${provided-march}
+
+endif # MARCH_DIRECTIVE
diff --git a/make_helpers/msys.mk b/make_helpers/msys.mk
new file mode 100644
index 0000000..7e60d57
--- /dev/null
+++ b/make_helpers/msys.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+# OS specific definitions for builds in a Mingw32 MSYS environment.
+# Mingw32 allows us to use some unix style commands on a windows platform.
+
+ifndef MSYS_MK
+ MSYS_MK := $(lastword $(MAKEFILE_LIST))
+
+ include ${MAKE_HELPERS_DIRECTORY}unix.mk
+
+ # In MSYS executable files have the Windows .exe extension type.
+ BIN_EXT := .exe
+
+endif
+
diff --git a/make_helpers/plat_helpers.mk b/make_helpers/plat_helpers.mk
new file mode 100644
index 0000000..a7ae9a2
--- /dev/null
+++ b/make_helpers/plat_helpers.mk
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+################################################################################
+# Helpers for finding and referencing platform directories
+################################################################################
+
+ifndef PLAT_HELPERS_MK
+ PLAT_HELPERS_MK := $(lastword $(MAKEFILE_LIST))
+
+ ifeq (${PLAT},)
+ $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform")
+ endif
+
+ # TF_PLATFORM_ROOT can be overridden for when building tools directly
+ TF_PLATFORM_ROOT ?= plat/
+ PLAT_MAKEFILE := platform.mk
+
+ # Generate the platforms list by recursively searching for all directories
+ # under /plat containing a PLAT_MAKEFILE. Append each platform with a `|`
+ # char and strip out the final '|'.
+ ALL_PLATFORM_MK_FILES := $(call rwildcard,${TF_PLATFORM_ROOT},${PLAT_MAKEFILE})
+ ALL_PLATFORM_DIRS := $(patsubst %/,%,$(dir ${ALL_PLATFORM_MK_FILES}))
+ ALL_PLATFORMS := $(sort $(notdir ${ALL_PLATFORM_DIRS}))
+
+ PLAT_MAKEFILE_FULL := $(filter %/${PLAT}/${PLAT_MAKEFILE},${ALL_PLATFORM_MK_FILES})
+ PLATFORM_LIST := $(subst ${space},|,${ALL_PLATFORMS})
+ ifeq ($(PLAT_MAKEFILE_FULL),)
+ $(error "Error: Invalid platform. The following platforms are available: ${PLATFORM_LIST}")
+ endif
+
+ # Record the directory where the platform make file was found.
+ PLAT_DIR := $(dir ${PLAT_MAKEFILE_FULL})
+
+endif
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
new file mode 100644
index 0000000..3a2c53f
--- /dev/null
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -0,0 +1,146 @@
+#
+# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# This file defines the keys and certificates that must be created to establish
+# a Chain of Trust following the TBBR document. These definitions include the
+# command line options passed to the cert_create and fiptool commands.
+#
+# Expected environment:
+#
+# BUILD_PLAT: output directory
+# NEED_BL2: indicates whether BL2 is needed by the platform
+# NEED_BL32: indicates whether BL32 is needed by the platform
+# BL2: image filename (optional). Default is IMG_BIN(2) (see macro IMG_BIN)
+# SCP_BL2: image filename (optional). Default is IMG_BIN(30)
+# BL31: image filename (optional). Default is IMG_BIN(31)
+# BL32: image filename (optional). Default is IMG_BIN(32)
+# BL33: image filename (optional). Default is IMG_BIN(33)
+#
+# Build options added by this file:
+#
+# KEY_ALG
+# KEY_SIZE
+# ROT_KEY
+# PROT_KEY
+# PLAT_KEY
+# SWD_ROT_KEY
+# CORE_SWD_KEY
+# TRUSTED_WORLD_KEY
+# NON_TRUSTED_WORLD_KEY
+# SCP_BL2_KEY
+# BL31_KEY
+# BL32_KEY
+# BL33_KEY
+#
+
+# Certificate generation tool default parameters
+TRUSTED_KEY_CERT ?= ${BUILD_PLAT}/trusted_key.crt
+FWU_CERT := ${BUILD_PLAT}/fwu_cert.crt
+
+# Default non-volatile counter values (overridable by the platform)
+TFW_NVCTR_VAL ?= 0
+NTFW_NVCTR_VAL ?= 0
+CCAFW_NVCTR_VAL ?= 0
+
+# Pass the non-volatile counters to the cert_create tool
+$(eval $(call CERT_ADD_CMD_OPT,${TFW_NVCTR_VAL},--tfw-nvctr))
+$(eval $(call CERT_ADD_CMD_OPT,${NTFW_NVCTR_VAL},--ntfw-nvctr))
+ifeq (${COT},cca)
+$(eval $(call CERT_ADD_CMD_OPT,${CCAFW_NVCTR_VAL},--ccafw-nvctr))
+endif
+
+# Add Trusted Key certificate to the fiptool and cert_create command line options
+ifneq (${COT},cca)
+$(eval $(call TOOL_ADD_PAYLOAD,${TRUSTED_KEY_CERT},--trusted-key-cert))
+else
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/cca.crt,--cca-cert))
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/core-swd.crt,--core-swd-cert))
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat-key.crt,--plat-key-cert))
+endif
+
+# Add fwu certificate to the fiptool and cert_create command line options
+ifneq (${COT},cca)
+$(eval $(call TOOL_ADD_PAYLOAD,${FWU_CERT},--fwu-cert,,FWU_))
+endif
+
+# Add the keys to the cert_create command line options (private keys are NOT
+# packed in the FIP). Developers can use their own keys by specifying the proper
+# build option in the command line when building the Trusted Firmware
+$(if ${KEY_ALG},$(eval $(call CERT_ADD_CMD_OPT,${KEY_ALG},--key-alg)))
+$(if ${KEY_ALG},$(eval $(call CERT_ADD_CMD_OPT,${KEY_ALG},--key-alg,FWU_)))
+$(if ${KEY_SIZE},$(eval $(call CERT_ADD_CMD_OPT,${KEY_SIZE},--key-size)))
+$(if ${KEY_SIZE},$(eval $(call CERT_ADD_CMD_OPT,${KEY_SIZE},--key-size,FWU_)))
+$(if ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-alg)))
+$(if ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-alg,FWU_)))
+$(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key)))
+$(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,FWU_)))
+$(if ${PROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PROT_KEY},--prot-key)))
+$(if ${PLAT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PLAT_KEY},--plat-key)))
+$(if ${SWD_ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${SWD_ROT_KEY},--swd-rot-key)))
+$(if ${CORE_SWD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${CORE_SWD_KEY},--core-swd-key)))
+$(if ${TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_WORLD_KEY},--trusted-world-key)))
+$(if ${NON_TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${NON_TRUSTED_WORLD_KEY},--non-trusted-world-key)))
+
+
+# Add the BL2 CoT (image cert)
+ifeq (${NEED_BL2},yes)
+ifeq (${RESET_TO_BL2}, 0)
+ifneq (${COT},cca)
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
+endif
+endif
+endif
+
+# Add the SCP_BL2 CoT (key cert + img cert)
+ifneq (${SCP_BL2},)
+ifneq (${COT},cca)
+ $(if ${SCP_BL2_KEY},$(eval $(call CERT_ADD_CMD_OPT,${SCP_BL2_KEY},--scp-fw-key)))
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/scp_fw_content.crt,--scp-fw-cert))
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/scp_fw_key.crt,--scp-fw-key-cert))
+endif
+endif
+
+ifeq (${ARCH},aarch64)
+ifeq (${NEED_BL31},yes)
+# Add the BL31 CoT (key cert + img cert)
+$(if ${BL31_KEY},$(eval $(call CERT_ADD_CMD_OPT,${BL31_KEY},--soc-fw-key)))
+ifneq (${COT},cca)
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_content.crt,--soc-fw-cert))
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_key.crt,--soc-fw-key-cert))
+endif
+endif
+endif
+
+# Add the BL32 CoT (key cert + img cert)
+ifeq (${NEED_BL32},yes)
+ $(if ${BL32_KEY},$(eval $(call CERT_ADD_CMD_OPT,${BL32_KEY},--tos-fw-key)))
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tos_fw_content.crt,--tos-fw-cert))
+ifneq (${COT},cca)
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tos_fw_key.crt,--tos-fw-key-cert))
+endif
+endif
+
+# Add the BL33 CoT (key cert + img cert)
+ifneq (${BL33},)
+ $(if ${BL33_KEY},$(eval $(call CERT_ADD_CMD_OPT,${BL33_KEY},--nt-fw-key)))
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_content.crt,--nt-fw-cert))
+ifneq (${COT},dualroot)
+ ifneq (${COT},cca)
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_key.crt,--nt-fw-key-cert))
+ endif
+endif
+endif
+
+# Add SiP owned Secure Partitions CoT (image cert)
+ifneq (${SP_LAYOUT_FILE},)
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/sip_sp_content.crt,--sip-sp-cert))
+ifeq (${COT},dualroot)
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat_sp_content.crt,--plat-sp-cert))
+endif
+ifeq (${COT},cca)
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat_sp_content.crt,--plat-sp-cert))
+endif
+endif
diff --git a/make_helpers/unix.mk b/make_helpers/unix.mk
new file mode 100644
index 0000000..545ddfd
--- /dev/null
+++ b/make_helpers/unix.mk
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Trusted Firmware shell command definitions for a Unix style environment.
+
+ifndef UNIX_MK
+ UNIX_MK := $(lastword $(MAKEFILE_LIST))
+
+ ECHO_BLANK_LINE := echo
+ ECHO_QUIET := @\#
+
+ DIR_DELIM := /
+ PATH_SEP := :
+
+ # These defines provide Unix style equivalents of the shell commands
+ # required by the Trusted Firmware build environment.
+
+ # ${1} is the file to be copied.
+ # ${2} is the destination file name.
+ define SHELL_COPY
+ ${Q}cp -f "${1}" "${2}"
+ endef
+
+ # ${1} is the directory to be copied.
+ # ${2} is the destination directory path.
+ define SHELL_COPY_TREE
+ ${Q}cp -rf "${1}" "${2}"
+ endef
+
+ # ${1} is the file to be deleted.
+ define SHELL_DELETE
+ -${Q}rm -f "${1}"
+ endef
+
+ # ${1} is a space delimited list of files to be deleted.
+ # Note that we do not quote ${1}, as multiple parameters may be passed.
+ define SHELL_DELETE_ALL
+ -${Q}rm -rf ${1}
+ endef
+
+ # ${1} is the directory to be generated.
+ # ${2} is optional, and allows a prerequisite to be specified.
+ # Do nothing if $1 == $2, to ignore self dependencies.
+ define MAKE_PREREQ_DIR
+ ifneq (${1},${2})
+
+${1} : ${2}
+ ${Q}mkdir -p "${1}"
+
+ endif
+ endef
+
+ define SHELL_REMOVE_DIR
+ -${Q}rm -rf "${1}"
+ endef
+
+endif
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
new file mode 100644
index 0000000..ac0f940
--- /dev/null
+++ b/make_helpers/windows.mk
@@ -0,0 +1,92 @@
+#
+# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# OS specific parts for builds in a Windows_NT environment. The
+# environment variable OS is set to Windows_NT on all modern Windows platforms
+
+# Include generic windows command definitions.
+
+ifndef WINDOWS_MK
+ WINDOWS_MK := $(lastword $(MAKEFILE_LIST))
+
+ ECHO_BLANK_LINE := @cmd /c echo.
+ ECHO_QUIET := @rem
+ DIR_DELIM := $(strip \)
+ BIN_EXT := .exe
+ PATH_SEP := ;
+
+ # For some Windows native commands there is a problem with the directory delimiter.
+ # Make uses / (slash) and the commands expect \ (backslash)
+ # We have to provide a means of translating these, so we define local functions.
+
+ # ${1} is the file to be copied.
+ # ${2} is the destination file name.
+ define SHELL_COPY
+ $(eval tmp_from_file:=$(subst /,\,${1}))
+ $(eval tmp_to_file:=$(subst /,\,${2}))
+ copy "${tmp_from_file}" "${tmp_to_file}"
+ endef
+
+ # ${1} is the directory to be copied.
+ # ${2} is the destination directory path.
+ define SHELL_COPY_TREE
+ $(eval tmp_from_dir:=$(subst /,\,${1}))
+ $(eval tmp_to_dir:=$(subst /,\,${2}))
+ xcopy /HIVE "${tmp_from_dir}" "${tmp_to_dir}"
+ endef
+
+ # ${1} is the file to be deleted.
+ define SHELL_DELETE
+ $(eval tmp_del_file:=$(subst /,\,${*}))
+ -@if exist $(tmp_del_file) del /Q $(tmp_del_file)
+ endef
+
+ # ${1} is a space delimited list of files to be deleted.
+ define SHELL_DELETE_ALL
+ $(eval $(foreach filename,$(wildcard ${1}),$(call DELETE_IF_THERE,${filename})))
+ endef
+
+ # ${1} is the directory to be generated.
+ # ${2} is optional, and allows prerequisites to be specified.
+ # Do nothing if $1 == $2, to ignore self dependencies.
+ define MAKE_PREREQ_DIR
+ ifneq (${1},${2})
+
+${1} : ${2}
+ $(eval tmp_dir:=$(subst /,\,${1}))
+ -@if not exist "$(tmp_dir)" mkdir "${tmp_dir}"
+
+ endif
+ endef
+
+ # ${1} is the directory to be removed.
+ define SHELL_REMOVE_DIR
+ $(eval tmp_dir:=$(subst /,\,${1}))
+ -@if exist "$(tmp_dir)" rd /Q /S "$(tmp_dir)"
+ endef
+
+endif
+
+# Because git is not available from CMD.EXE, we need to avoid
+# the BUILD_STRING generation which uses git.
+# For now we use "development build".
+# This can be overridden from the command line or environment.
+BUILD_STRING ?= development build
+
+# The DOS echo shell command does not strip ' characters from the command
+# parameters before printing. We therefore use an alternative method invoked
+# by defining the MAKE_BUILD_STRINGS macro.
+BUILT_TIME_DATE_STRING = const char build_message[] = "Built : "${BUILD_MESSAGE_TIMESTAMP};
+VERSION_STRING_MESSAGE = const char version_string[] = "${VERSION_STRING}";
+VERSION_MESSAGE = const char version[] = "${VERSION}";
+define MAKE_BUILD_STRINGS
+ $$(file >$1.in,$$(TF_CFLAGS) $$(CFLAGS))
+ @echo $$(BUILT_TIME_DATE_STRING) $$(VERSION_STRING_MESSAGE) $$(VERSION_MESSAGE) | \
+ $$(CC) @$1.in -x c -c - -o $1
+endef
+
+MSVC_NMAKE := nmake.exe
+