refactor(context-mgmt): move FEAT_FGT save/restore code into C

At the moment we do the EL2 context save/restore sequence in assembly,
where it is just guarded by #ifdef statement for the build time flags.
This does not cover the FEAT_STATE_CHECK case, where we need to check
for the runtime availability of a feature.

To simplify this extension, and to avoid writing too much code in
assembly, move that sequence into C: it is called from C context
anyways.

This protects the C code with the new version of the is_xxx_present()
check, which combines both build time and runtime check, as necessary,
and allows the compiler to optimise the calls aways, if we don't need
them.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Change-Id: I7c91bec60efcc00a43429dc0381f7e1c203be780
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 5010ac5..86c1dbe 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -565,6 +565,14 @@
 DEFINE_RENAME_SYSREG_READ_FUNC(rndr, RNDR)
 DEFINE_RENAME_SYSREG_READ_FUNC(rndrrs, RNDRRS)
 
+/* Armv8.6 FEAT_FGT Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(hdfgrtr_el2, HDFGRTR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hafgrtr_el2, HAFGRTR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hdfgwtr_el2, HDFGWTR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgitr_el2, HFGITR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgrtr_el2, HFGRTR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgwtr_el2, HFGWTR_EL2)
+
 /* FEAT_HCX Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2)
 
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 6c13166..27cf3b9 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -523,10 +523,6 @@
 void el2_sysregs_context_save_mpam(el2_sysregs_t *regs);
 void el2_sysregs_context_restore_mpam(el2_sysregs_t *regs);
 #endif /* ENABLE_MPAM_FOR_LOWER_ELS */
-#if ENABLE_FEAT_FGT
-void el2_sysregs_context_save_fgt(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_fgt(el2_sysregs_t *regs);
-#endif /* ENABLE_FEAT_FGT */
 #if ENABLE_FEAT_ECV
 void el2_sysregs_context_save_ecv(el2_sysregs_t *regs);
 void el2_sysregs_context_restore_ecv(el2_sysregs_t *regs);
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 60501f6..e0efec2 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -25,10 +25,6 @@
 	.global	el2_sysregs_context_save_mpam
 	.global	el2_sysregs_context_restore_mpam
 #endif /* ENABLE_MPAM_FOR_LOWER_ELS */
-#if ENABLE_FEAT_FGT
-	.global	el2_sysregs_context_save_fgt
-	.global	el2_sysregs_context_restore_fgt
-#endif /* ENABLE_FEAT_FGT */
 #if ENABLE_FEAT_ECV
 	.global	el2_sysregs_context_save_ecv
 	.global	el2_sysregs_context_restore_ecv
@@ -314,45 +310,6 @@
 endfunc el2_sysregs_context_restore_mpam
 #endif /* ENABLE_MPAM_FOR_LOWER_ELS */
 
-#if ENABLE_FEAT_FGT
-func el2_sysregs_context_save_fgt
-	mrs	x13, HDFGRTR_EL2
-#if ENABLE_FEAT_AMUv1
-	mrs	x14, HAFGRTR_EL2
-	stp	x13, x14, [x0, #CTX_HDFGRTR_EL2]
-#else
-	str	x13, [x0, #CTX_HDFGRTR_EL2]
-#endif /* ENABLE_FEAT_AMUv1 */
-	mrs	x15, HDFGWTR_EL2
-	mrs	x16, HFGITR_EL2
-	stp	x15, x16, [x0, #CTX_HDFGWTR_EL2]
-
-	mrs	x9, HFGRTR_EL2
-	mrs	x10, HFGWTR_EL2
-	stp	x9, x10, [x0, #CTX_HFGRTR_EL2]
-	ret
-endfunc el2_sysregs_context_save_fgt
-
-func el2_sysregs_context_restore_fgt
-	#if ENABLE_FEAT_AMUv1
-	ldp	x13, x14, [x0, #CTX_HDFGRTR_EL2]
-	msr	HAFGRTR_EL2, x14
-#else
-	ldr	x13, [x0, #CTX_HDFGRTR_EL2]
-#endif /* ENABLE_FEAT_AMUv1 */
-	msr	HDFGRTR_EL2, x13
-
-	ldp	x15, x16, [x0, #CTX_HDFGWTR_EL2]
-	msr	HDFGWTR_EL2, x15
-	msr	HFGITR_EL2, x16
-
-	ldp	x9, x10, [x0, #CTX_HFGRTR_EL2]
-	msr	HFGRTR_EL2, x9
-	msr	HFGWTR_EL2, x10
-	ret
-endfunc el2_sysregs_context_restore_fgt
-#endif /* ENABLE_FEAT_FGT */
-
 #if ENABLE_FEAT_ECV
 func el2_sysregs_context_save_ecv
 	mrs	x11, CNTPOFF_EL2
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 93d817f..46e191c 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -792,6 +792,35 @@
 }
 
 #if CTX_INCLUDE_EL2_REGS
+
+static void el2_sysregs_context_save_fgt(el2_sysregs_t *ctx)
+{
+	if (is_feat_fgt_supported()) {
+		write_ctx_reg(ctx, CTX_HDFGRTR_EL2, read_hdfgrtr_el2());
+		if (is_feat_amu_supported()) {
+			write_ctx_reg(ctx, CTX_HAFGRTR_EL2, read_hafgrtr_el2());
+		}
+		write_ctx_reg(ctx, CTX_HDFGWTR_EL2, read_hdfgwtr_el2());
+		write_ctx_reg(ctx, CTX_HFGITR_EL2, read_hfgitr_el2());
+		write_ctx_reg(ctx, CTX_HFGRTR_EL2, read_hfgrtr_el2());
+		write_ctx_reg(ctx, CTX_HFGWTR_EL2, read_hfgwtr_el2());
+	}
+}
+
+static void el2_sysregs_context_restore_fgt(el2_sysregs_t *ctx)
+{
+	if (is_feat_fgt_supported()) {
+		write_hdfgrtr_el2(read_ctx_reg(ctx, CTX_HDFGRTR_EL2));
+		if (is_feat_amu_supported()) {
+			write_hafgrtr_el2(read_ctx_reg(ctx, CTX_HAFGRTR_EL2));
+		}
+		write_hdfgwtr_el2(read_ctx_reg(ctx, CTX_HDFGWTR_EL2));
+		write_hfgitr_el2(read_ctx_reg(ctx, CTX_HFGITR_EL2));
+		write_hfgrtr_el2(read_ctx_reg(ctx, CTX_HFGRTR_EL2));
+		write_hfgwtr_el2(read_ctx_reg(ctx, CTX_HFGWTR_EL2));
+	}
+}
+
 /*******************************************************************************
  * Save EL2 sysreg context
  ******************************************************************************/
@@ -823,9 +852,9 @@
 #if ENABLE_MPAM_FOR_LOWER_ELS
 		el2_sysregs_context_save_mpam(el2_sysregs_ctx);
 #endif
-#if ENABLE_FEAT_FGT
+
 		el2_sysregs_context_save_fgt(el2_sysregs_ctx);
-#endif
+
 #if ENABLE_FEAT_ECV
 		el2_sysregs_context_save_ecv(el2_sysregs_ctx);
 #endif
@@ -881,9 +910,9 @@
 #if ENABLE_MPAM_FOR_LOWER_ELS
 		el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
 #endif
-#if ENABLE_FEAT_FGT
+
 		el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
-#endif
+
 #if ENABLE_FEAT_ECV
 		el2_sysregs_context_restore_ecv(el2_sysregs_ctx);
 #endif