feat(rmmd): add support to create a boot manifest

This patch also adds an initial RMM Boot Manifest (v0.1) for fvp
platform.

Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
Change-Id: I1374f8f9cb207028f1820953cd2a5cf6d6c3b948
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 87c4ccb..bfe0031 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -2081,6 +2081,19 @@
 failure). A pointer to the shared area (or a NULL pointer on failure) is stored
 in the pointer passed as argument.
 
+Function : plat_rmmd_load_manifest() [when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Arguments : rmm_manifest_t *manifest
+    Return    : int
+
+When ENABLE_RME is enabled, this function populates a boot manifest for the
+RMM image and stores it in the area specified by manifest.
+
+When ENABLE_RME is disabled, this function is not used.
+
 Function : bl31_plat_enable_mmu [optional]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 479a48b..184606a 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -13,6 +13,9 @@
 #if defined(SPD_spmd)
  #include <services/spm_core_manifest.h>
 #endif
+#if ENABLE_RME
+#include <services/rmm_core_manifest.h>
+#endif
 #if TRNG_SUPPORT
 #include "plat_trng.h"
 #endif
@@ -305,11 +308,15 @@
 /*******************************************************************************
  * Mandatory BL31 functions when ENABLE_RME=1
  ******************************************************************************/
+#if ENABLE_RME
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
 				   uintptr_t hash, size_t hash_size);
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type);
 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
+int plat_rmmd_load_manifest(rmm_manifest_t *manifest);
+#endif
+
 /*******************************************************************************
  * Optional BL31 functions (may be overridden)
  ******************************************************************************/
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
new file mode 100644
index 0000000..2f25858
--- /dev/null
+++ b/include/services/rmm_core_manifest.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RMM_CORE_MANIFEST_H
+#define RMM_CORE_MANIFEST_H
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/cassert.h>
+
+#define RMMD_MANIFEST_VERSION_MAJOR		U(0)
+#define RMMD_MANIFEST_VERSION_MINOR		U(1)
+
+/*
+ * Manifest version encoding:
+ *	- Bit[31] RES0
+ *	- Bits [30:16] Major version
+ *	- Bits [15:0] Minor version
+ */
+#define _RMMD_MANIFEST_VERSION(_major, _minor)				\
+	((((_major) & 0x7FFF) << 16) | ((_minor) & 0xFFFF))
+
+#define RMMD_MANIFEST_VERSION _RMMD_MANIFEST_VERSION(			\
+				RMMD_MANIFEST_VERSION_MAJOR,		\
+				RMMD_MANIFEST_VERSION_MINOR)
+
+#define RMMD_GET_MANIFEST_VERSION_MAJOR(_version)			\
+	((_version >> 16) & 0x7FFF)
+
+#define RMMD_GET_MANIFEST_VERSION_MINOR(_version)			\
+	(_version & 0xFFFF)
+
+/* Boot manifest core structure as per v0.1 */
+typedef struct rmm_manifest {
+	uint32_t version;	/* Manifest version */
+	uintptr_t plat_data;	/* Manifest platform data */
+} rmm_manifest_t;
+
+CASSERT(offsetof(rmm_manifest_t, version) == 0,
+				rmm_manifest_t_version_unaligned);
+CASSERT(offsetof(rmm_manifest_t, plat_data) == 8,
+				rmm_manifest_t_plat_data_unaligned);
+
+#endif /* RMM_CORE_MANIFEST_H */
diff --git a/include/services/trp/platform_trp.h b/include/services/trp/platform_trp.h
index b34da85..1c963c8 100644
--- a/include/services/trp/platform_trp.h
+++ b/include/services/trp/platform_trp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,9 +7,11 @@
 #ifndef PLATFORM_TRP_H
 #define PLATFORM_TRP_H
 
+#include <services/rmm_core_manifest.h>
+
 /*******************************************************************************
  * Mandatory TRP functions (only if platform contains a TRP)
  ******************************************************************************/
-void trp_early_platform_setup(void);
+void trp_early_platform_setup(rmm_manifest_t *manifest);
 
 #endif /* PLATFORM_TRP_H */
diff --git a/include/services/trp/trp_helpers.h b/include/services/trp/trp_helpers.h
new file mode 100644
index 0000000..8e786e2
--- /dev/null
+++ b/include/services/trp/trp_helpers.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRP_HELPERS_H
+#define TRP_HELPERS_H
+
+/* Definitions to help the assembler access the SMC/ERET args structure */
+#define TRP_ARGS_SIZE		TRP_ARGS_END
+#define TRP_ARG0		0x0
+#define TRP_ARG1		0x8
+#define TRP_ARG2		0x10
+#define TRP_ARG3		0x18
+#define TRP_ARG4		0x20
+#define TRP_ARG5		0x28
+#define TRP_ARG6		0x30
+#define TRP_ARG7		0x38
+#define TRP_ARGS_END		0x40
+
+#ifndef __ASSEMBLER__
+
+#include <platform_def.h>
+
+/* Data structure to hold SMC arguments */
+typedef struct trp_args {
+	uint64_t regs[TRP_ARGS_END >> 3];
+} __aligned(CACHE_WRITEBACK_GRANULE) trp_args_t;
+
+trp_args_t *set_smc_args(uint64_t arg0,
+			 uint64_t arg1,
+			 uint64_t arg2,
+			 uint64_t arg3,
+			 uint64_t arg4,
+			 uint64_t arg5,
+			 uint64_t arg6,
+			 uint64_t arg7);
+
+__dead2 void trp_boot_abort(uint64_t err);
+
+#endif /* __ASSEMBLER __ */
+#endif /* TRP_HELPERS_H */
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 45a4721..f8463f1 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -17,6 +17,9 @@
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <platform_def.h>
 #include <services/arm_arch_svc.h>
+#if ENABLE_RME
+#include <services/rmm_core_manifest.h>
+#endif
 #if SPM_MM
 #include <services/spm_mm_partition.h>
 #endif
@@ -527,4 +530,15 @@
 
 	return (size_t)RMM_SHARED_SIZE;
 }
+
+int plat_rmmd_load_manifest(rmm_manifest_t *manifest)
+{
+	assert(manifest != NULL);
+
+	manifest->version = RMMD_MANIFEST_VERSION;
+	manifest->plat_data = (uintptr_t)NULL;
+
+	return 0;
+}
+
 #endif
diff --git a/plat/arm/common/trp/arm_trp.mk b/plat/arm/common/trp/arm_trp.mk
index 997111f..204c14a 100644
--- a/plat/arm/common/trp/arm_trp.mk
+++ b/plat/arm/common/trp/arm_trp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,3 +8,5 @@
 RMM_SOURCES		+=	plat/arm/common/trp/arm_trp_setup.c	\
 				plat/arm/common/arm_topology.c		\
 				plat/common/aarch64/platform_mp_stack.S
+
+INCLUDES		+=	-Iinclude/services/trp
diff --git a/plat/arm/common/trp/arm_trp_setup.c b/plat/arm/common/trp/arm_trp_setup.c
index 8e48293..59b4c06 100644
--- a/plat/arm/common/trp/arm_trp_setup.c
+++ b/plat/arm/common/trp/arm_trp_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,33 +8,65 @@
 #include <common/debug.h>
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
+#include <services/rmm_core_manifest.h>
+#include <services/rmmd_svc.h>
+#include <services/trp/platform_trp.h>
+#include <trp_helpers.h>
+
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
 
 /*******************************************************************************
+ * Received from boot manifest and populated here
+ ******************************************************************************/
+extern uint32_t trp_boot_manifest_version;
+
+/*******************************************************************************
  * Initialize the UART
  ******************************************************************************/
 static console_t arm_trp_runtime_console;
 
+static int arm_trp_process_manifest(rmm_manifest_t *manifest)
+{
+	/* Verify the Boot Manifest Version. Only the Major is considered */
+	if (RMMD_MANIFEST_VERSION_MAJOR !=
+		RMMD_GET_MANIFEST_VERSION_MAJOR(manifest->version)) {
+		return E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED;
+	}
+
-void arm_trp_early_platform_setup(void)
+	trp_boot_manifest_version = manifest->version;
+	flush_dcache_range((uintptr_t)manifest, sizeof(rmm_manifest_t));
+
+	return 0;
+}
+
+void arm_trp_early_platform_setup(rmm_manifest_t *manifest)
 {
+	int rc;
+
+	rc = arm_trp_process_manifest(manifest);
+	if (rc != 0) {
+		trp_boot_abort(rc);
+	}
+
 	/*
 	 * Initialize a different console than already in use to display
 	 * messages from trp
 	 */
-	int rc = console_pl011_register(PLAT_ARM_TRP_UART_BASE,
-					PLAT_ARM_TRP_UART_CLK_IN_HZ,
-					ARM_CONSOLE_BAUDRATE,
-					&arm_trp_runtime_console);
+	rc = console_pl011_register(PLAT_ARM_TRP_UART_BASE,
+				    PLAT_ARM_TRP_UART_CLK_IN_HZ,
+				    ARM_CONSOLE_BAUDRATE,
+				    &arm_trp_runtime_console);
 	if (rc == 0) {
 		panic();
 	}
 
 	console_set_scope(&arm_trp_runtime_console,
 			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+
 }
 
-void trp_early_platform_setup(void)
+void trp_early_platform_setup(rmm_manifest_t *manifest)
 {
-	arm_trp_early_platform_setup();
+	arm_trp_early_platform_setup(manifest);
 }
diff --git a/services/std_svc/rmmd/rmmd_attest.c b/services/std_svc/rmmd/rmmd_attest.c
index 355b034..25adf50 100644
--- a/services/std_svc/rmmd/rmmd_attest.c
+++ b/services/std_svc/rmmd/rmmd_attest.c
@@ -5,6 +5,7 @@
  */
 #include <stdint.h>
 #include <string.h>
+
 #include <common/debug.h>
 #include <lib/spinlock.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 27a1ad9..322d9f2 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -171,6 +171,8 @@
 	uint32_t ep_attr;
 	unsigned int linear_id = plat_my_core_pos();
 	rmmd_rmm_context_t *rmm_ctx = &rmm_context[linear_id];
+	rmm_manifest_t *manifest;
+	int rc;
 
 	/* Make sure RME is supported. */
 	assert(get_armv9_2_feat_rme_support() != 0U);
@@ -203,6 +205,15 @@
 	assert((shared_buf_size == SZ_4K) &&
 					((void *)shared_buf_base != NULL));
 
+	/* Load the boot manifest at the beginning of the shared area */
+	manifest = (rmm_manifest_t *)shared_buf_base;
+	rc = plat_rmmd_load_manifest(manifest);
+	if (rc != 0) {
+		ERROR("Error loading RMM Boot Manifest (%i)\n", rc);
+		return rc;
+	}
+	flush_dcache_range((uintptr_t)shared_buf_base, shared_buf_size);
+
 	/*
 	 * Prepare coldboot arguments for RMM:
 	 * arg0: This CPUID (primary processor).
diff --git a/services/std_svc/rmmd/trp/trp.mk b/services/std_svc/rmmd/trp/trp.mk
index a4f6e03..44bbf22 100644
--- a/services/std_svc/rmmd/trp/trp.mk
+++ b/services/std_svc/rmmd/trp/trp.mk
@@ -1,11 +1,12 @@
 #
-# Copyright (c) 2021 Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022 Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-RMM_SOURCES		+=	services/std_svc/rmmd/trp/trp_entry.S	\
-				services/std_svc/rmmd/trp/trp_main.c
+RMM_SOURCES		+=	services/std_svc/rmmd/trp/trp_entry.S \
+				services/std_svc/rmmd/trp/trp_main.c  \
+				services/std_svc/rmmd/trp/trp_helpers.c
 
 RMM_LINKERFILE		:=	services/std_svc/rmmd/trp/linker.lds
 
diff --git a/services/std_svc/rmmd/trp/trp_helpers.c b/services/std_svc/rmmd/trp/trp_helpers.c
new file mode 100644
index 0000000..159f3a5
--- /dev/null
+++ b/services/std_svc/rmmd/trp/trp_helpers.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <plat/common/platform.h>
+#include <services/rmmd_svc.h>
+#include "trp_private.h"
+
+/*
+ * Per cpu data structure to populate parameters for an SMC in C code and use
+ * a pointer to this structure in assembler code to populate x0-x7
+ */
+static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT];
+
+/*
+ * Set the arguments for SMC call
+ */
+trp_args_t *set_smc_args(uint64_t arg0,
+			uint64_t arg1,
+			uint64_t arg2,
+			uint64_t arg3,
+			uint64_t arg4,
+			uint64_t arg5,
+			uint64_t arg6,
+			uint64_t arg7)
+{
+	uint32_t linear_id;
+	trp_args_t *pcpu_smc_args;
+
+	/*
+	 * Return to Secure Monitor by raising an SMC. The results of the
+	 * service are passed as an arguments to the SMC
+	 */
+	linear_id = plat_my_core_pos();
+	pcpu_smc_args = &trp_smc_args[linear_id];
+	write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0);
+	write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1);
+	write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2);
+	write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3);
+	write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4);
+	write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5);
+	write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6);
+	write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7);
+
+	return pcpu_smc_args;
+}
+
+/*
+ * Abort the boot process with the reason given in err.
+ */
+__dead2 void trp_boot_abort(uint64_t err)
+{
+	(void)trp_smc(set_smc_args(RMM_BOOT_COMPLETE, err, 0, 0, 0, 0, 0, 0));
+	panic();
+}
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 7df128b..cf6ec7b 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -7,63 +7,20 @@
 
 #include <common/debug.h>
 #include <plat/common/platform.h>
+#include <services/rmm_core_manifest.h>
 #include <services/rmmd_svc.h>
 #include <services/trp/platform_trp.h>
+#include <trp_helpers.h>
+#include "trp_private.h"
 
 #include <platform_def.h>
-#include "trp_private.h"
 
 /* Parameters received from the previous image */
 static unsigned int trp_boot_abi_version;
 static uintptr_t trp_shared_region_start;
 
-/*******************************************************************************
- * Per cpu data structure to populate parameters for an SMC in C code and use
- * a pointer to this structure in assembler code to populate x0-x7
- ******************************************************************************/
-static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT];
-
-/*******************************************************************************
- * Set the arguments for SMC call
- ******************************************************************************/
-static trp_args_t *set_smc_args(uint64_t arg0,
-				uint64_t arg1,
-				uint64_t arg2,
-				uint64_t arg3,
-				uint64_t arg4,
-				uint64_t arg5,
-				uint64_t arg6,
-				uint64_t arg7)
-{
-	uint32_t linear_id;
-	trp_args_t *pcpu_smc_args;
-
-	/*
-	 * Return to Secure Monitor by raising an SMC. The results of the
-	 * service are passed as an arguments to the SMC
-	 */
-	linear_id = plat_my_core_pos();
-	pcpu_smc_args = &trp_smc_args[linear_id];
-	write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0);
-	write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1);
-	write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2);
-	write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3);
-	write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4);
-	write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5);
-	write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6);
-	write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7);
-
-	return pcpu_smc_args;
-}
-
-/*
- * Abort the boot process with the reason given in err.
- */
-__dead2 static void trp_boot_abort(uint64_t err)
-{
-	(void)trp_smc(set_smc_args(RMM_BOOT_COMPLETE, err, 0, 0, 0, 0, 0, 0));
-	panic();
-}
+/* Parameters received from boot manifest */
+uint32_t trp_boot_manifest_version;
 
 /*******************************************************************************
  * Setup function for TRP.
@@ -106,7 +63,7 @@
 			   sizeof(trp_shared_region_start));
 
 	/* Perform early platform-specific setup */
-	trp_early_platform_setup();
+	trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start);
 }
 
 /* Main function for TRP */
@@ -116,6 +73,9 @@
 	NOTICE("TRP: %s\n", build_message);
 	NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
 		TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
+	NOTICE("TRP: Boot Manifest Version : v.%u.%u\n",
+		RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version),
+		RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version));
 	INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE);
 	INFO("TRP: Base address for the shared region : 0x%lx\n",
 			(unsigned long)trp_shared_region_start);
diff --git a/services/std_svc/rmmd/trp/trp_private.h b/services/std_svc/rmmd/trp/trp_private.h
index f3a4876..945ae1c 100644
--- a/services/std_svc/rmmd/trp/trp_private.h
+++ b/services/std_svc/rmmd/trp/trp_private.h
@@ -8,18 +8,7 @@
 #define TRP_PRIVATE_H
 
 #include <services/rmmd_svc.h>
-
-/* Definitions to help the assembler access the SMC/ERET args structure */
-#define TRP_ARGS_SIZE		TRP_ARGS_END
-#define TRP_ARG0		0x0
-#define TRP_ARG1		0x8
-#define TRP_ARG2		0x10
-#define TRP_ARG3		0x18
-#define TRP_ARG4		0x20
-#define TRP_ARG5		0x28
-#define TRP_ARG6		0x30
-#define TRP_ARG7		0x38
-#define TRP_ARGS_END		0x40
+#include <trp_helpers.h>
 
 /* Definitions for RMM-EL3 Interface ABI VERSION */
 #define TRP_RMM_EL3_ABI_VERS_MAJOR	RMM_EL3_IFC_VERSION_MAJOR
@@ -33,11 +22,6 @@
 
 #include <stdint.h>
 
-/* Data structure to hold SMC arguments */
-typedef struct trp_args {
-	uint64_t regs[TRP_ARGS_END >> 3];
-} __aligned(CACHE_WRITEBACK_GRANULE) trp_args_t;
-
 #define write_trp_arg(args, offset, val) (((args)->regs[offset >> 3])	\
 					 = val)
 /* RMI SMC64 FIDs handled by the TRP */