feat(cpufeat): enable FEAT_BTI to FEAT_STATE_CHECKED

Introduce the is_feat_bti_{supported, present}() helpers and replace
checks for ENABLE_BTI with it. Also factor out the setting of
SCTLR_EL3.BT out of the PAuth enablement and place it in the respective
entrypoints where we initialise SCTLR_EL3. This makes PAuth
self-contained and SCTLR_EL3 initialisation centralised.

Change-Id: I0c0657ff1e78a9652cd2cf1603478283dc01f17b
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S
index a021e42..756c16d 100644
--- a/bl2/aarch64/bl2_entrypoint.S
+++ b/bl2/aarch64/bl2_entrypoint.S
@@ -48,6 +48,10 @@
 	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
 	mrs	x0, sctlr_el1
 	orr	x0, x0, x1
+#if ENABLE_BTI
+	/* Enable PAC branch type compatibility */
+	bic     x0, x0, #(SCTLR_BT0_BIT | SCTLR_BT1_BIT)
+#endif
 	bic	x0, x0, #SCTLR_DSSBS_BIT
 	msr	sctlr_el1, x0
 	isb
diff --git a/bl2u/aarch64/bl2u_entrypoint.S b/bl2u/aarch64/bl2u_entrypoint.S
index 15978b6..8fc34b3 100644
--- a/bl2u/aarch64/bl2u_entrypoint.S
+++ b/bl2u/aarch64/bl2u_entrypoint.S
@@ -45,6 +45,10 @@
 	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
 	mrs	x0, sctlr_el1
 	orr	x0, x0, x1
+#if ENABLE_BTI
+	/* Enable PAC branch type compatibility */
+	bic     x0, x0, #(SCTLR_BT0_BIT | SCTLR_BT1_BIT)
+#endif
 	bic	x0, x0, #SCTLR_DSSBS_BIT
 	msr	sctlr_el1, x0
 	isb
diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S
index e5ea88c..b4e7a7a 100644
--- a/bl32/tsp/aarch64/tsp_entrypoint.S
+++ b/bl32/tsp/aarch64/tsp_entrypoint.S
@@ -94,6 +94,10 @@
 	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
 	mrs	x0, sctlr_el1
 	orr	x0, x0, x1
+#if ENABLE_BTI
+	/* Enable PAC branch type compatibility */
+	bic     x0, x0, #(SCTLR_BT0_BIT | SCTLR_BT1_BIT)
+#endif
 	bic	x0, x0, #SCTLR_DSSBS_BIT
 	msr	sctlr_el1, x0
 	isb
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index 243ac15..cc39a55 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -204,5 +204,7 @@
 static inline bool is_feat_ls64_accdata_present(void) { return false; }
 __attribute__((always_inline))
 static inline bool is_feat_mops_supported(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_bti_supported(void) { return false; }
 
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 43ff2cc..0dd44b4 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -199,8 +199,8 @@
 			ID_AA64MMFR2_EL1_ST_MASK, 1U)
 
 /* FEAT_BTI: Branch target identification */
-CREATE_FEATURE_PRESENT(feat_bti, id_aa64pfr1_el1, ID_AA64PFR1_EL1_BT_SHIFT,
-			ID_AA64PFR1_EL1_BT_MASK, BTI_IMPLEMENTED)
+CREATE_FEATURE_FUNCS(feat_bti, id_aa64pfr1_el1, ID_AA64PFR1_EL1_BT_SHIFT,
+			ID_AA64PFR1_EL1_BT_MASK, BTI_IMPLEMENTED, ENABLE_BTI)
 
 /* FEAT_MTE2: Memory tagging extension */
 CREATE_FEATURE_FUNCS(feat_mte2, id_aa64pfr1_el1, ID_AA64PFR1_EL1_MTE_SHIFT,
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 2f2aeaf..07dffb1 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -32,10 +32,15 @@
 	 *  load or store one or more registers have an alignment check that the
 	 *  address being accessed is aligned to the size of the data element(s)
 	 *  being accessed.
+	 *
+	 * SCTLR_EL3.BT: PAuth instructions are compatible with bti jc
 	 * ---------------------------------------------------------------------
 	 */
-	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+	mov_imm	x1, (SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
 	mrs	x0, sctlr_el3
+#if ENABLE_BTI
+	bic	x0, x0, #SCTLR_BT_BIT
+#endif
 	orr	x0, x0, x1
 	msr	sctlr_el3, x0
 	isb
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 5434a9a..f540fa5 100644
--- a/include/lib/xlat_tables/xlat_tables_defs.h
+++ b/include/lib/xlat_tables/xlat_tables_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,10 +62,8 @@
 #define OSH			(U(0x2) << 6)
 #define ISH			(U(0x3) << 6)
 
-#ifdef __aarch64__
 /* Guarded Page bit */
 #define GP			(ULL(1) << 50)
-#endif
 
 #define TABLE_ADDR_MASK		ULL(0x0000FFFFFFFFF000)
 
diff --git a/lib/extensions/pauth/pauth_helpers.S b/lib/extensions/pauth/pauth_helpers.S
index fb5fa97..1f0e2e0 100644
--- a/lib/extensions/pauth/pauth_helpers.S
+++ b/lib/extensions/pauth/pauth_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,11 +32,6 @@
 	/* Enable pointer authentication */
 	mrs	x0, sctlr_el1
 	orr	x0, x0, #SCTLR_EnIA_BIT
-
-#if ENABLE_BTI
-	 /* Enable PAC branch type compatibility */
-	bic	x0, x0, #(SCTLR_BT0_BIT | SCTLR_BT1_BIT)
-#endif
 	msr	sctlr_el1, x0
 	isb
 
@@ -73,11 +68,6 @@
 	/* Enable pointer authentication */
 	mrs	x0, sctlr_el3
 	orr	x0, x0, #SCTLR_EnIA_BIT
-
-#if ENABLE_BTI
-	 /* Enable PAC branch type compatibility */
-	bic	x0, x0, #SCTLR_BT_BIT
-#endif
 	msr	sctlr_el3, x0
 	isb
 
@@ -130,11 +120,6 @@
 	/* Enable pointer authentication */
 	mrs	x9, sctlr_el3
 	orr	x9, x9, #SCTLR_EnIA_BIT
-
-#if ENABLE_BTI
-	 /* Enable PAC branch type compatibility */
-	bic	x9, x9, #SCTLR_BT_BIT
-#endif
 	msr	sctlr_el3, x9
 	isb
 	ret
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index bd7f017..76aba50 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -210,17 +210,14 @@
 				desc |= LOWER_ATTRS(ISH);
 			}
 
-			/* Check if Branch Target Identification is enabled */
-#if ENABLE_BTI
 			/* Set GP bit for block and page code entries
 			 * if BTI mechanism is implemented.
 			 */
-			if (is_feat_bti_present() &&
+			if (is_feat_bti_supported() &&
 			   ((attr & (MT_TYPE_MASK | MT_RW |
 				MT_EXECUTE_NEVER)) == MT_CODE)) {
 				desc |= GP;
 			}
-#endif
 		} else {
 			assert(mem_type == MT_NON_CACHEABLE);
 			desc |= LOWER_ATTRS(ATTR_NON_CACHEABLE_INDEX | OSH);