TFTF: Add ARMv8.5 BTI support in makefiles

This patch adds 'BRANCH_PROTECTION' build option in
TFTF makefiles which corresponds to that in TF-A.
The option values are documented in 'build-options.rst'

Signed-off-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
Change-Id: Iad5083aee339cec574acf5e7ab1fd8142877a122
diff --git a/Makefile b/Makefile
index fea13db..a229d0a 100644
--- a/Makefile
+++ b/Makefile
@@ -149,13 +149,20 @@
 ################################################################################
 $(eval $(call assert_boolean,DEBUG))
 $(eval $(call assert_boolean,ENABLE_ASSERTIONS))
-$(eval $(call assert_boolean,ENABLE_PAUTH))
 $(eval $(call assert_boolean,FIRMWARE_UPDATE))
 $(eval $(call assert_boolean,FWU_BL_TEST))
 $(eval $(call assert_boolean,NEW_TEST_SESSION))
 $(eval $(call assert_boolean,USE_NVM))
 
 ################################################################################
+# Process build options
+################################################################################
+
+# Process BRANCH_PROTECTION value and set
+# Pointer Authentication and Branch Target Identification flags
+include branch_protection.mk
+
+################################################################################
 # Add definitions to the cpp preprocessor based on the current build options.
 # This is done after including the platform specific makefile to allow the
 # platform to overwrite the default options
@@ -164,6 +171,7 @@
 $(eval $(call add_define,TFTF_DEFINES,ARM_ARCH_MINOR))
 $(eval $(call add_define,TFTF_DEFINES,DEBUG))
 $(eval $(call add_define,TFTF_DEFINES,ENABLE_ASSERTIONS))
+$(eval $(call add_define,TFTF_DEFINES,ENABLE_BTI))
 $(eval $(call add_define,TFTF_DEFINES,ENABLE_PAUTH))
 $(eval $(call add_define,TFTF_DEFINES,LOG_LEVEL))
 $(eval $(call add_define,TFTF_DEFINES,NEW_TEST_SESSION))
@@ -230,10 +238,14 @@
 TFTF_ASFLAGS		+= ${COMMON_ASFLAGS}
 TFTF_LDFLAGS		+= ${COMMON_LDFLAGS}
 
-ifeq (${ENABLE_PAUTH},1)
-TFTF_CFLAGS		+= -mbranch-protection=pac-ret
-NS_BL1U_CFLAGS		+= -mbranch-protection=pac-ret
-NS_BL2U_CFLAGS		+= -mbranch-protection=pac-ret
+ifneq (${BP_OPTION},none)
+TFTF_CFLAGS		+= -mbranch-protection=${BP_OPTION}
+NS_BL1U_CFLAGS		+= -mbranch-protection=${BP_OPTION}
+NS_BL2U_CFLAGS		+= -mbranch-protection=${BP_OPTION}
+CACTUS_MM_CFLAGS	+= -mbranch-protection=${BP_OPTION}
+CACTUS_CFLAGS		+= -mbranch-protection=${BP_OPTION}
+IVY_CFLAGS		+= -mbranch-protection=${BP_OPTION}
+QUARK_CFLAGS		+= -mbranch-protection=${BP_OPTION}
 endif
 
 #####################################################################################
diff --git a/branch_protection.mk b/branch_protection.mk
new file mode 100644
index 0000000..c16cdad
--- /dev/null
+++ b/branch_protection.mk
@@ -0,0 +1,52 @@
+#
+# Copyright (c) 2020, 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.
+
+# Select the branch protection features to use.
+BRANCH_PROTECTION	:= 0
+
+# Flag to enable Branch Target Identification in the TFTF.
+# Internal flag not meant for direct setting.
+# Use BRANCH_PROTECTION to enable BTI.
+ENABLE_BTI		:= 0
+
+# Enable Pointer Authentication support in the TFTF.
+# Internal flag not meant for direct setting.
+# Use BRANCH_PROTECTION to enable PAUTH.
+ENABLE_PAUTH		:= 0
+
+# Process BRANCH_PROTECTION value and set
+# Pointer Authentication and Branch Target Identification flags
+ifeq (${BRANCH_PROTECTION},0)
+	# Default value turns off all types of branch protection
+	BP_OPTION := none
+else ifneq (${ARCH},aarch64)
+        $(error BRANCH_PROTECTION requires AArch64)
+else ifeq (${BRANCH_PROTECTION},1)
+	# Enables all types of branch protection features
+	BP_OPTION := standard
+	ENABLE_BTI := 1
+	ENABLE_PAUTH := 1
+else ifeq (${BRANCH_PROTECTION},2)
+	# Return address signing to its standard level
+	BP_OPTION := pac-ret
+	ENABLE_PAUTH := 1
+else ifeq (${BRANCH_PROTECTION},3)
+	# Extend the signing to include leaf functions
+	BP_OPTION := pac-ret+leaf
+	ENABLE_PAUTH := 1
+else ifeq (${BRANCH_PROTECTION},4)
+	# Turn on branch target identification mechanism
+	BP_OPTION := bti
+	ENABLE_BTI := 1
+else
+        $(error Unknown BRANCH_PROTECTION value ${BRANCH_PROTECTION})
+endif
diff --git a/defaults.mk b/defaults.mk
index cf90aaf..ca44b47 100644
--- a/defaults.mk
+++ b/defaults.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -26,9 +26,6 @@
 # Build platform
 DEFAULT_PLAT		:= fvp
 
-# Enable Pointer Authentication support in the TFTF
-ENABLE_PAUTH		:= 0
-
 # Whether the Firmware Update images (i.e. NS_BL1U and NS_BL2U images) should be
 # built. The platform makefile is free to override this value.
 FIRMWARE_UPDATE		:= 0
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 95724e7..8815466 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -30,6 +30,37 @@
 -  ``ARM_ARCH_MINOR``: The minor version of Arm Architecture to target when
    compiling TF-A Tests. Its value must be a numeric, and defaults to 0.
 
+-  ``BRANCH_PROTECTION``: Numeric value to enable ARMv8.3 Pointer Authentication
+   (``ARMv8.3-PAuth``) and ARMv8.5 Branch Target Identification (``ARMv8.5-BTI``)
+   support in the Trusted Firmware-A Test Framework itself.
+   If enabled, it is needed to use a compiler that supports the option
+   ``-mbranch-protection`` (GCC 9 and later).
+   Selects the branch protection features to use:
+-  0: Default value turns off all types of branch protection
+-  1: Enables all types of branch protection features
+-  2: Return address signing to its standard level
+-  3: Extend the signing to include leaf functions
+-  4: Turn on branch target identification mechanism
+
+   The table below summarizes ``BRANCH_PROTECTION`` values, GCC compilation
+   options and resulting PAuth/BTI features.
+
+   +-------+--------------+-------+-----+
+   | Value |  GCC option  | PAuth | BTI |
+   +=======+==============+=======+=====+
+   |   0   |     none     |   N   |  N  |
+   +-------+--------------+-------+-----+
+   |   1   |   standard   |   Y   |  Y  |
+   +-------+--------------+-------+-----+
+   |   2   |   pac-ret    |   Y   |  N  |
+   +-------+--------------+-------+-----+
+   |   3   | pac-ret+leaf |   Y   |  N  |
+   +-------+--------------+-------+-----+
+   |   4   |     bti      |   N   |  Y  |
+   +-------+--------------+-------+-----+
+
+   This option defaults to 0 and this is an experimental feature.
+
 -  ``DEBUG``: Chooses between a debug and a release build. A debug build
    typically embeds assertions checking the validity of some assumptions and its
    output is more verbose. The option can take either 0 (release) or 1 (debug)
@@ -90,11 +121,6 @@
 TFTF-specific Build Options
 ---------------------------
 
--  ``ENABLE_PAUTH``: Boolean option to enable ARMv8.3 Pointer Authentication
-   (``ARMv8.3-PAuth``) support in the Trusted Firmware-A Test Framework itself.
-   If enabled, it is needed to use a compiler that supports the option
-   ``-mbranch-protection`` (GCC 9 and later). It defaults to 0.
-
 -  ``NEW_TEST_SESSION``: Choose whether a new test session should be started
    every time or whether the framework should determine whether a previous
    session was interrupted and resume it. It can take either 1 (always
diff --git a/fwu/ns_bl1u/ns_bl1u.mk b/fwu/ns_bl1u/ns_bl1u.mk
index 7e0e767..2b45b8d 100644
--- a/fwu/ns_bl1u/ns_bl1u.mk
+++ b/fwu/ns_bl1u/ns_bl1u.mk
@@ -4,6 +4,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+include branch_protection.mk
 include lib/xlat_tables_v2/xlat_tables.mk
 include lib/compiler-rt/compiler-rt.mk
 
@@ -67,9 +68,8 @@
 $(eval $(call add_define,NS_BL1U_DEFINES,ARM_ARCH_MINOR))
 $(eval $(call add_define,NS_BL1U_DEFINES,DEBUG))
 $(eval $(call add_define,NS_BL1U_DEFINES,ENABLE_ASSERTIONS))
+$(eval $(call add_define,NS_BL1U_DEFINES,ENABLE_BTI))
+$(eval $(call add_define,NS_BL1U_DEFINES,ENABLE_PAUTH))
 $(eval $(call add_define,NS_BL1U_DEFINES,FWU_BL_TEST))
 $(eval $(call add_define,NS_BL1U_DEFINES,LOG_LEVEL))
 $(eval $(call add_define,NS_BL1U_DEFINES,PLAT_${PLAT}))
-ifeq (${ARCH},aarch64)
-        $(eval $(call add_define,NS_BL1U_DEFINES,ENABLE_PAUTH))
-endif
diff --git a/fwu/ns_bl2u/ns_bl2u.mk b/fwu/ns_bl2u/ns_bl2u.mk
index b6e616e..0864313 100644
--- a/fwu/ns_bl2u/ns_bl2u.mk
+++ b/fwu/ns_bl2u/ns_bl2u.mk
@@ -4,6 +4,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+include branch_protection.mk
 include lib/xlat_tables_v2/xlat_tables.mk
 include lib/compiler-rt/compiler-rt.mk
 
@@ -62,9 +63,8 @@
 $(eval $(call add_define,NS_BL2U_DEFINES,ARM_ARCH_MINOR))
 $(eval $(call add_define,NS_BL2U_DEFINES,DEBUG))
 $(eval $(call add_define,NS_BL2U_DEFINES,ENABLE_ASSERTIONS))
+$(eval $(call add_define,NS_BL2U_DEFINES,ENABLE_BTI))
+$(eval $(call add_define,NS_BL2U_DEFINES,ENABLE_PAUTH))
 $(eval $(call add_define,NS_BL2U_DEFINES,FWU_BL_TEST))
 $(eval $(call add_define,NS_BL2U_DEFINES,LOG_LEVEL))
 $(eval $(call add_define,NS_BL2U_DEFINES,PLAT_${PLAT}))
-ifeq (${ARCH},aarch64)
-        $(eval $(call add_define,NS_BL2U_DEFINES,ENABLE_PAUTH))
-endif
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index d98cd2a..60f6974 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -4,6 +4,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+include branch_protection.mk
 include lib/xlat_tables_v2/xlat_tables.mk
 
 CACTUS_DTB	:= $(BUILD_PLAT)/cactus.dtb
@@ -53,11 +54,15 @@
 
 CACTUS_DEFINES	:=
 
+$(eval $(call add_define,CACTUS_DEFINES,ARM_ARCH_MAJOR))
+$(eval $(call add_define,CACTUS_DEFINES,ARM_ARCH_MINOR))
 $(eval $(call add_define,CACTUS_DEFINES,DEBUG))
+$(eval $(call add_define,CACTUS_DEFINES,ENABLE_ASSERTIONS))
+$(eval $(call add_define,CACTUS_DEFINES,ENABLE_BTI))
+$(eval $(call add_define,CACTUS_DEFINES,ENABLE_PAUTH))
 $(eval $(call add_define,CACTUS_DEFINES,FVP_CLUSTER_COUNT))
 $(eval $(call add_define,CACTUS_DEFINES,FVP_MAX_CPUS_PER_CLUSTER))
 $(eval $(call add_define,CACTUS_DEFINES,FVP_MAX_PE_PER_CPU))
-$(eval $(call add_define,CACTUS_DEFINES,ENABLE_ASSERTIONS))
 $(eval $(call add_define,CACTUS_DEFINES,LOG_LEVEL))
 $(eval $(call add_define,CACTUS_DEFINES,PLAT_${PLAT}))
 
diff --git a/spm/cactus_mm/cactus_mm.mk b/spm/cactus_mm/cactus_mm.mk
index 6d69061..3156c1c 100644
--- a/spm/cactus_mm/cactus_mm.mk
+++ b/spm/cactus_mm/cactus_mm.mk
@@ -4,6 +4,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+include branch_protection.mk
+
 CACTUS_MM_INCLUDES :=					\
 	-Iinclude					\
 	-Iinclude/common				\
@@ -52,7 +54,11 @@
 # that is done.
 CACTUS_MM_DEFINES	+= -DENABLE_ASSERTIONS=0
 
+$(eval $(call add_define,CACTUS_MM_DEFINES,ARM_ARCH_MAJOR))
+$(eval $(call add_define,CACTUS_MM_DEFINES,ARM_ARCH_MINOR))
 $(eval $(call add_define,CACTUS_MM_DEFINES,DEBUG))
+$(eval $(call add_define,CACTUS_MM_DEFINES,ENABLE_BTI))
+$(eval $(call add_define,CACTUS_MM_DEFINES,ENABLE_PAUTH))
 $(eval $(call add_define,CACTUS_MM_DEFINES,FVP_CLUSTER_COUNT))
 $(eval $(call add_define,CACTUS_MM_DEFINES,FVP_MAX_CPUS_PER_CLUSTER))
 $(eval $(call add_define,CACTUS_MM_DEFINES,FVP_MAX_PE_PER_CPU))
diff --git a/spm/ivy/ivy.mk b/spm/ivy/ivy.mk
index afc89f4..a500049 100644
--- a/spm/ivy/ivy.mk
+++ b/spm/ivy/ivy.mk
@@ -4,6 +4,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+include branch_protection.mk
 include lib/sprt/sprt_client.mk
 
 IVY_DTB		:= $(BUILD_PLAT)/ivy.dtb
@@ -50,8 +51,12 @@
 
 IVY_DEFINES	:=
 
+$(eval $(call add_define,IVY_DEFINES,ARM_ARCH_MAJOR))
+$(eval $(call add_define,IVY_DEFINES,ARM_ARCH_MINOR))
 $(eval $(call add_define,IVY_DEFINES,DEBUG))
 $(eval $(call add_define,IVY_DEFINES,ENABLE_ASSERTIONS))
+$(eval $(call add_define,IVY_DEFINES,ENABLE_BTI))
+$(eval $(call add_define,IVY_DEFINES,ENABLE_PAUTH))
 $(eval $(call add_define,IVY_DEFINES,FVP_CLUSTER_COUNT))
 $(eval $(call add_define,IVY_DEFINES,FVP_MAX_CPUS_PER_CLUSTER))
 $(eval $(call add_define,IVY_DEFINES,FVP_MAX_PE_PER_CPU))
diff --git a/spm/quark/quark.mk b/spm/quark/quark.mk
index ec4a3ed..0fe1646 100644
--- a/spm/quark/quark.mk
+++ b/spm/quark/quark.mk
@@ -4,6 +4,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+include branch_protection.mk
 include lib/sprt/sprt_client.mk
 
 QUARK_DTB		:= $(BUILD_PLAT)/quark.dtb
@@ -47,8 +48,12 @@
 
 QUARK_DEFINES	:=
 
+$(eval $(call add_define,QUARK_DEFINES,ARM_ARCH_MAJOR))
+$(eval $(call add_define,QUARK_DEFINES,ARM_ARCH_MINOR))
 $(eval $(call add_define,QUARK_DEFINES,DEBUG))
 $(eval $(call add_define,QUARK_DEFINES,ENABLE_ASSERTIONS))
+$(eval $(call add_define,QUARK_DEFINES,ENABLE_BTI))
+$(eval $(call add_define,QUARK_DEFINES,ENABLE_PAUTH))
 $(eval $(call add_define,QUARK_DEFINES,FVP_CLUSTER_COUNT))
 $(eval $(call add_define,QUARK_DEFINES,FVP_MAX_CPUS_PER_CLUSTER))
 $(eval $(call add_define,QUARK_DEFINES,FVP_MAX_PE_PER_CPU))