Merge "feat: tftf realm extension"
diff --git a/Makefile b/Makefile
index 55f9690..4af1b2a 100644
--- a/Makefile
+++ b/Makefile
@@ -119,6 +119,7 @@
 ifeq (${ARCH}-${PLAT},aarch64-fvp)
 include spm/cactus_mm/cactus_mm.mk
 include spm/quark/quark.mk
+include realm/realm.mk
 endif
 
 # cactus and ivy are supported on platforms: fvp, tc0
@@ -306,6 +307,11 @@
 QUARK_ASFLAGS		+= ${COMMON_ASFLAGS}
 QUARK_LDFLAGS		+= ${COMMON_LDFLAGS}
 
+REALM_SOURCES		+= ${LIBC_SRCS}
+REALM_CFLAGS		+= ${COMMON_CFLAGS} -fpie
+REALM_ASFLAGS		+= ${COMMON_ASFLAGS}
+REALM_LDFLAGS		+= ${COMMON_LDFLAGS} $(PIE_LDFLAGS)
+
 .PHONY: locate-checkpatch
 locate-checkpatch:
 ifndef CHECKPATCH
@@ -382,6 +388,16 @@
 quark:
 	@echo "ERROR: $@ is supported only on AArch64 FVP."
 	@exit 1
+
+.PHONY: realm
+realm:
+	@echo "ERROR: $@ is supported only on AArch64 FVP."
+	@exit 1
+
+.PHONY: pack_realm
+pack_realm:
+	@echo "Nothing to be done"
+	@exit 1
 endif
 
 ifneq (${ARCH}-${PLAT},$(filter ${ARCH}-${PLAT},aarch64-fvp aarch64-tc0))
@@ -531,6 +547,15 @@
   $(eval $(call MAKE_IMG,cactus))
   $(eval $(call MAKE_IMG,ivy))
   $(eval $(call MAKE_IMG,quark))
+  $(eval $(call MAKE_IMG,realm))
+endif
+
+ifeq (${ARCH}-${PLAT},aarch64-fvp)
+.PHONY : pack_realm
+pack_realm: realm tftf
+	@echo "  PACK REALM PAYLOAD"
+	$(shell dd if=$(BUILD_PLAT)/realm.bin of=$(BUILD_PLAT)/tftf.bin obs=1 \
+	seek=$(TFTF_MAX_IMAGE_SIZE))
 endif
 
 ifeq (${ARCH}-${PLAT},aarch64-tc0)
@@ -569,7 +594,7 @@
 .SILENT: help
 help:
 	echo "usage: ${MAKE} PLAT=<${PLATFORMS}> \
-<all|tftf|ns_bl1u|ns_bl2u|cactus|ivy|quark|el3_payload|distclean|clean|checkcodebase|checkpatch|help_tests>"
+<all|tftf|ns_bl1u|ns_bl2u|cactus|ivy|quark|realm|pack_realm|el3_payload|distclean|clean|checkcodebase|checkpatch|help_tests>"
 	echo ""
 	echo "PLAT is used to specify which platform you wish to build."
 	echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
@@ -581,6 +606,8 @@
 	echo "  ns_bl1u        Build the NS_BL1U image"
 	echo "  ns_bl2u        Build the NS_BL2U image"
 	echo "  cactus         Build the Cactus image (Test S-EL0 payload) and resource description."
+	echo "  realm          Build the Realm image (Test R-EL1 payload)."
+	echo "  pack_realm     Pack the realm image to tftf.bin."
 	echo "  cactus_mm      Build the Cactus-MM image (Test S-EL0 payload)."
 	echo "  ivy            Build the Ivy image (Test S-EL0 payload) and resource description."
 	echo "  quark          Build the Quark image (Test S-EL0 payload) and resource description."
diff --git a/include/common/debug.h b/include/common/debug.h
index 4b30175..6025590 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2014-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,11 @@
 void mp_printf(const char *fmt, ...);
 #endif /* IMAGE_CACTUS_MM */
 
+#ifdef IMAGE_REALM
+void realm_printf(const char *fmt, ...);
+#define mp_printf realm_printf
+#endif
+
 /*
  * The log output macros print output to the console. These macros produce
  * compiled log output only if the LOG_LEVEL defined in the makefile (or the
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index a4b7d7d..230d69a 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -505,6 +505,50 @@
 #define CNTP_CTL_IMASK_MASK     U(1)
 #define CNTP_CTL_ISTATUS_MASK   U(1)
 
+/* Exception Syndrome register bits and bobs */
+#define ESR_EC_SHIFT			U(26)
+#define ESR_EC_MASK			U(0x3f)
+#define ESR_EC_LENGTH			U(6)
+#define ESR_ISS_SHIFT			U(0x0)
+#define ESR_ISS_MASK			U(0x1ffffff)
+#define EC_UNKNOWN			U(0x0)
+#define EC_WFE_WFI			U(0x1)
+#define EC_CP15_MRC_MCR			U(0x3)
+#define EC_CP15_MRRC_MCRR		U(0x4)
+#define EC_CP14_MRC_MCR			U(0x5)
+#define EC_CP14_LDC_STC			U(0x6)
+#define EC_FP_SIMD			U(0x7)
+#define EC_CP10_MRC			U(0x8)
+#define EC_CP14_MRRC_MCRR		U(0xc)
+#define EC_ILLEGAL			U(0xe)
+#define EC_SVC				U(0x11)
+#define EC_HVC				U(0x12)
+#define EC_SMC				U(0x13)
+#define EC_IABORT_LOWER_EL		U(0x20)
+#define EC_IABORT_CUR_EL		U(0x21)
+#define EC_PC_ALIGN			U(0x22)
+#define EC_DABORT_LOWER_EL		U(0x24)
+#define EC_DABORT_CUR_EL		U(0x25)
+#define EC_SP_ALIGN			U(0x26)
+#define EC_FP				U(0x28)
+#define EC_SERROR			U(0x2f)
+/* Data Fault Status code, not all error codes listed */
+#define ISS_DFSC_MASK			U(0x3f)
+#define DFSC_EXT_DABORT			U(0x10)
+#define DFSC_GPF_DABORT			U(0x28)
+/* ISS encoding an exception from HVC or SVC instruction execution */
+#define ISS_HVC_SMC_IMM16_MASK		U(0xffff)
+
+/*
+ * External Abort bit in Instruction and Data Aborts synchronous exception
+ * syndromes.
+ */
+#define ESR_ISS_EABORT_EA_BIT		U(9)
+
+#define EC_BITS(x)			(((x) >> ESR_EC_SHIFT) & ESR_EC_MASK)
+#define ISS_BITS(x)			(((x) >> ESR_ISS_SHIFT) & ESR_ISS_MASK)
+
+
 /* MAIR macros */
 #define MAIR0_ATTR_SET(attr, index)	((attr) << ((index) << U(3)))
 #define MAIR1_ATTR_SET(attr, index)	((attr) << (((index) - U(3)) << U(3)))
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 534e1cf..e436e6b 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -717,6 +717,8 @@
 #define ISS_DFSC_MASK			U(0x3f)
 #define DFSC_EXT_DABORT			U(0x10)
 #define DFSC_GPF_DABORT			U(0x28)
+/* ISS encoding an exception from HVC or SVC instruction execution */
+#define ISS_HVC_SMC_IMM16_MASK		U(0xffff)
 
 /*
  * External Abort bit in Instruction and Data Aborts synchronous exception
diff --git a/include/lib/heap/page_alloc.h b/include/lib/heap/page_alloc.h
new file mode 100644
index 0000000..7580b78
--- /dev/null
+++ b/include/lib/heap/page_alloc.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PAGE_ALLOC_H
+#define PAGE_ALLOC_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#define HEAP_NULL_PTR		0U
+#define HEAP_INVALID_LEN	-1
+#define HEAP_OUT_OF_RANGE	-2
+#define HEAP_INIT_FAILED	-3
+#define HEAP_INIT_SUCCESS	0
+
+/*
+ * Initialize the memory heap space to be used
+ * @heap_base: heap base address
+ * @heap_len: heap size for use
+ */
+int page_pool_init(uint64_t heap_base, uint64_t heap_len);
+
+/*
+ * Return the pointer to the allocated pages
+ * @bytes_size: pages to allocate in byte unit
+ */
+void *page_alloc(u_register_t bytes_size);
+
+/*
+ * Reset heap memory usage cursor to heap base address
+ */
+void page_pool_reset(void);
+void page_free(u_register_t ptr);
+
+#endif /* PAGE_ALLOC_H */
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 78d4131..9638495 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -162,4 +162,20 @@
 
 #define COMPILER_BARRIER() __asm__ volatile ("" ::: "memory")
 
+#define MASK(regfield) \
+	((~0ULL >> (64ULL - (regfield##_WIDTH))) << (regfield##_SHIFT))
+
+#define EXTRACT(regfield, reg) \
+	(((reg) & MASK(regfield)) >> (regfield##_SHIFT))
+
+/*
+ * Defines member of structure and reserves space
+ * for the next member with specified offset.
+ */
+#define SET_MEMBER(member, start, end)	\
+	union {				\
+		member;			\
+		unsigned char reserved##end[end - start]; \
+	}
+
 #endif /* UTILS_DEF_H */
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 1fd3c83..ba0559c 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-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -179,4 +179,24 @@
 #define XN_SHIFT			54
 #define UXN_SHIFT			XN_SHIFT
 
+/*
+ * Stage 2 translation Lower attributes
+ */
+#define S2TTE_AP_SHIFT			6
+#define S2TTE_AP_RW			(3UL << S2TTE_AP_SHIFT)
+
+#define S2TTE_SH_SHIFT			8
+#define S2TTE_SH_MASK			(3UL << S2TTE_SH_SHIFT)
+#define S2TTE_SH_NS			(0UL << S2TTE_SH_SHIFT)
+#define S2TTE_SH_OS			(2UL << S2TTE_SH_SHIFT)
+#define S2TTE_SH_IS			(3UL << S2TTE_SH_SHIFT)
+
+/*
+ * Attributes when FEAT_S2FWB is enabled at EL2 (HCR_EL2.FWB == 1).
+ * For Normal WB cacheability attribute, set bit[4] to 1 and bits[3:2] to 0b10.
+ */
+#define S2TTE_MEMATTR_FWB_NORMAL_WB	((1UL << 4) | (2UL << 2))
+#define S2TTE_ATTR_FWB_WB_RW	(S2TTE_MEMATTR_FWB_NORMAL_WB | S2TTE_AP_RW | \
+			S2TTE_SH_IS)
+
 #endif /* XLAT_TABLES_DEFS_H */
diff --git a/include/runtime_services/host_realm_managment/host_realm_helper.h b/include/runtime_services/host_realm_managment/host_realm_helper.h
new file mode 100644
index 0000000..a103630
--- /dev/null
+++ b/include/runtime_services/host_realm_managment/host_realm_helper.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef HOST_REALM_HELPER_H
+#define HOST_REALM_HELPER_H
+
+#include <host_realm_rmi.h>
+
+bool host_create_realm_payload(u_register_t realm_payload_adr,
+		u_register_t plat_mem_pool_adr,
+		u_register_t plat_mem_pool_size,
+		u_register_t realm_pages_size);
+bool host_create_shared_mem(
+		u_register_t ns_shared_mem_adr,
+		u_register_t ns_shared_mem_size);
+bool host_destroy_realm(void);
+bool host_enter_realm_execute(uint8_t cmd);
+
+#endif /* HOST_REALM_HELPER_H */
+
diff --git a/include/runtime_services/host_realm_managment/host_realm_mem_layout.h b/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
new file mode 100644
index 0000000..2c5a605
--- /dev/null
+++ b/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HOST_REALM_MEM_LAYOUT_H
+#define HOST_REALM_MEM_LAYOUT_H
+
+#include <realm_def.h>
+
+#include <platform_def.h>
+
+/*
+ * Realm payload Memory Usage Layout
+ *
+ * +--------------------------+     +---------------------------+
+ * |                          |     | Host Image                |
+ * |    TFTF                  |     | (TFTF_MAX_IMAGE_SIZE)     |
+ * | Normal World             | ==> +---------------------------+
+ * |    Image                 |     | Realm Image               |
+ * | (MAX_NS_IMAGE_SIZE)      |     | (REALM_MAX_LOAD_IMG_SIZE  |
+ * +--------------------------+     +---------------------------+
+ * |  Memory Pool             |     | Heap Memory               |
+ * | (NS_REALM_SHARED_MEM_SIZE|     | (PAGE_POOL_MAX_SIZE)      |
+ * |  + PAGE_POOL_MAX_SIZE)   | ==> |                           |
+ * |                          |     |                           |
+ * |                          |     +---------------------------+
+ * |                          |     | Shared Region             |
+ * |                          |     | (NS_REALM_SHARED_MEM_SIZE)|
+ * +--------------------------+     +---------------------------+
+ *
+ */
+
+/*
+ * Default values defined in platform.mk, and can be provided as build arguments
+ * TFTF_MAX_IMAGE_SIZE: 1mb
+ */
+
+#ifdef TFTF_MAX_IMAGE_SIZE
+/* 1MB for shared buffer between Realm and Host*/
+ #define NS_REALM_SHARED_MEM_SIZE	U(0x100000)
+/* 3MB of memory used as a pool for realm's objects creation*/
+ #define PAGE_POOL_MAX_SIZE		U(0x300000)
+/* Base address of each section */
+ #define REALM_IMAGE_BASE		(TFTF_BASE + TFTF_MAX_IMAGE_SIZE)
+ #define PAGE_POOL_BASE			(REALM_IMAGE_BASE + REALM_MAX_LOAD_IMG_SIZE)
+ #define NS_REALM_SHARED_MEM_BASE	(PAGE_POOL_BASE + PAGE_POOL_MAX_SIZE)
+#else
+ #define NS_REALM_SHARED_MEM_SIZE	0U
+ #define PAGE_POOL_MAX_SIZE		0U
+ #define TFTF_MAX_IMAGE_SIZE		DRAM_SIZE
+/* Base address of each section */
+ #define REALM_IMAGE_BASE		0U
+ #define PAGE_POOL_BASE			0U
+ #define NS_REALM_SHARED_MEM_BASE	0U
+#endif
+
+#endif /* HOST_REALM_MEM_LAYOUT_H */
diff --git a/include/runtime_services/host_realm_managment/host_realm_rmi.h b/include/runtime_services/host_realm_managment/host_realm_rmi.h
new file mode 100644
index 0000000..4e5f8c6
--- /dev/null
+++ b/include/runtime_services/host_realm_managment/host_realm_rmi.h
@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HOST_REALM_RMI_H
+#define HOST_REALM_RMI_H
+
+#include <stdint.h>
+
+#include <realm_rsi.h>
+#include <smccc.h>
+#include <utils_def.h>
+
+#define RMI_FNUM_MIN_VALUE	U(0x150)
+#define RMI_FNUM_MAX_VALUE	U(0x18F)
+
+/* Get RMI fastcall std FID from offset */
+#define SMC64_RMI_FID(_offset)					\
+	((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) |			\
+	(SMC_64 << FUNCID_CC_SHIFT) |				\
+	(OEN_STD_START << FUNCID_OEN_SHIFT) |			\
+	(((RMI_FNUM_MIN_VALUE + (_offset)) & FUNCID_NUM_MASK)	\
+	<< FUNCID_NUM_SHIFT))
+
+#define RMI_ABI_VERSION_GET_MAJOR(_version)	(((_version) >> 16U) & 0x8FFF)
+#define RMI_ABI_VERSION_GET_MINOR(_version)	((_version) & 0xFFFF)
+
+#define __ALIGN_MASK(x, mask)		(((x) + (mask)) & ~(mask))
+#define __ALIGN(x, a)			__ALIGN_MASK(x, (typeof(x))(a) - 1U)
+#define ALIGN(x, a)			__ALIGN((x), (a))
+
+/*
+ * SMC_RMM_INIT_COMPLETE is the only function in the RMI that originates from
+ * the Realm world and is handled by the RMMD. The remaining functions are
+ * always invoked by the Normal world, forwarded by RMMD and handled by the
+ * RMM
+ */
+/* RMI SMC64 FIDs handled by the RMMD */
+/* no parameters */
+#define RMI_VERSION			SMC64_RMI_FID(U(0x0))
+
+/*
+ * arg0 == target granule address
+ */
+#define RMI_GRANULE_DELEGATE		SMC64_RMI_FID(U(0x1))
+
+/*
+ * arg0 == target granule address
+ */
+#define RMI_GRANULE_UNDELEGATE		SMC64_RMI_FID(U(0x2))
+
+/*
+ * arg0 == data address
+ * arg1 == RD address
+ * arg2 == map address
+ * arg3 == SRC address
+ */
+#define RMI_DATA_CREATE			SMC64_RMI_FID(U(0x3))
+
+/*
+ * arg0 == data address
+ * arg1 == RD address
+ * arg2 == map address
+ */
+#define RMI_DATA_CREATE_UNKNOWN		SMC64_RMI_FID(U(0x4))
+
+/*
+ * arg0 == RD address
+ * arg1 == map address
+ */
+#define RMI_DATA_DESTROY		SMC64_RMI_FID(U(0x5))
+
+/*
+ * arg0 == RD address
+ */
+#define RMI_REALM_ACTIVATE		SMC64_RMI_FID(U(0x7))
+
+/*
+ * arg0 == RD address
+ * arg1 == struct rmi_realm_params addr
+ */
+#define RMI_REALM_CREATE		SMC64_RMI_FID(U(0x8))
+
+/*
+ * arg0 == RD address
+ */
+#define RMI_REALM_DESTROY		SMC64_RMI_FID(U(0x9))
+
+/*
+ * arg0 == REC address
+ * arg1 == RD address
+ * arg2 == struct rmm_rec address
+ */
+#define RMI_REC_CREATE			SMC64_RMI_FID(U(0xA))
+
+/*
+ * arg0 == REC address
+ */
+#define RMI_REC_DESTROY			SMC64_RMI_FID(U(0xB))
+
+/*
+ * arg0 == rec address
+ * arg1 == rec_run address
+ */
+#define RMI_REC_ENTER			SMC64_RMI_FID(U(0xC))
+
+/*
+ * arg0 == RTT address
+ * arg1 == RD address
+ * arg2 == map address
+ * arg3 == level
+ */
+#define RMI_RTT_CREATE			SMC64_RMI_FID(U(0xD))
+
+/*
+ * arg0 == RTT address
+ * arg1 == RD address
+ * arg2 == map address
+ * arg3 == level
+ */
+#define RMI_RTT_DESTROY			SMC64_RMI_FID(U(0xE))
+
+/*
+ * arg0 == RD address
+ * arg1 == map address
+ * arg2 == level
+ * arg3 == s2tte
+ */
+#define RMI_RTT_MAP_UNPROTECTED		SMC64_RMI_FID(U(0xF))
+
+/*
+ * arg0 == RD address
+ * arg1 == map address
+ * arg2 == level
+ * ret1 == level
+ * ret2 == s2tte type
+ * ret3 == s2tte
+ * ret4 == ripas
+ */
+#define RMI_RTT_READ_ENTRY		SMC64_RMI_FID(U(0x11))
+
+/*
+ * arg0 == RD address
+ * arg1 == map address
+ * arg2 == level
+ */
+#define RMI_RTT_UNMAP_UNPROTECTED	SMC64_RMI_FID(U(0x12))
+
+/*
+ * arg0 == calling rec address
+ * arg1 == target rec address
+ */
+#define RMI_PSCI_COMPLETE		SMC64_RMI_FID(U(0x14))
+
+/*
+ * arg0 == Feature register index
+ */
+#define RMI_FEATURES			SMC64_RMI_FID(U(0x15))
+
+/*
+ * arg0 == RTT address
+ * arg1 == RD address
+ * arg2 == map address
+ * arg3 == level
+ */
+#define RMI_RTT_FOLD			SMC64_RMI_FID(U(0x16))
+
+/*
+ * arg0 == RD address
+ */
+#define RMI_REC_AUX_COUNT		SMC64_RMI_FID(U(0x17))
+
+/*
+ * arg1 == RD address
+ * arg2 == map address
+ * arg3 == level
+ */
+#define RMI_RTT_INIT_RIPAS		SMC64_RMI_FID(U(0x18))
+
+/*
+ * arg0 == RD address
+ * arg1 == REC address
+ * arg2 == map address
+ * arg3 == level
+ * arg4 == ripas
+ */
+#define RMI_RTT_SET_RIPAS		SMC64_RMI_FID(U(0x19))
+
+#define GRANULE_SIZE			PAGE_SIZE_4KB
+
+/* Maximum number of auxiliary granules required for a REC */
+#define MAX_REC_AUX_GRANULES		16U
+#define REC_PARAMS_AUX_GRANULES		16U
+#define REC_EXIT_NR_GPRS		31U
+/* Size of Realm Personalization Value */
+#define RPV_SIZE			64U
+/* RmiDisposeResponse types */
+#define RMI_DISPOSE_ACCEPT		0U
+#define RMI_DISPOSE_REJECT		1U
+
+/* RmiFeatureLpa2 types */
+#define RMI_NO_LPA2			0U
+#define RMI_LPA2			1U
+
+/* RmiInterfaceVersion type */
+#define RMI_MAJOR_VERSION		0U
+#define RMI_MINOR_VERSION		0U
+
+/* RmiRealmMeasurementAlgorithm types */
+#define RMI_HASH_SHA_256		0U
+#define RMI_HASH_SHA_512		1U
+
+/* RmiRecEmulatedMmio types */
+#define RMI_NOT_EMULATED_MMIO		0U
+#define RMI_EMULATED_MMIO		1U
+
+/*
+ * RmiRecExitReason represents the reason for a REC exit.
+ * This is returned to NS hosts via RMI_REC_ENTER::run_ptr.
+ */
+#define RMI_EXIT_SYNC			0U
+#define RMI_EXIT_IRQ			1U
+#define RMI_EXIT_FIQ			2U
+#define RMI_EXIT_PSCI			3U
+#define RMI_EXIT_RIPAS_CHANGE		4U
+#define RMI_EXIT_HOST_CALL		5U
+#define RMI_EXIT_SERROR			6U
+#define RMI_EXIT_INVALID		0xFFFFFU
+
+/* RmiRecRunnable types */
+#define RMI_NOT_RUNNABLE		0U
+#define RMI_RUNNABLE			1U
+
+/* RttEntryState: represents the state of an RTTE */
+#define RMI_UNASSIGNED			0U
+#define RMI_DESTROYED			1U
+#define RMI_ASSIGNED			2U
+#define RMI_TABLE			3U
+#define RMI_VALID_NS			4U
+
+#define RMI_FEATURE_REGISTER_0_S2SZ		GENMASK(7, 0)
+#define RMI_FEATURE_REGISTER_0_LPA2		BIT(8)
+#define RMI_FEATURE_REGISTER_0_SVE_EN		BIT(9)
+#define RMI_FEATURE_REGISTER_0_SVE_VL		GENMASK(13, 10)
+#define RMI_FEATURE_REGISTER_0_NUM_BPS		GENMASK(17, 14)
+#define RMI_FEATURE_REGISTER_0_NUM_WPS		GENMASK(21, 18)
+#define RMI_FEATURE_REGISTER_0_PMU_EN		BIT(22)
+#define RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS	GENMASK(27, 23)
+#define RMI_FEATURE_REGISTER_0_HASH_SHA_256	BIT(28)
+#define RMI_FEATURE_REGISTER_0_HASH_SHA_512	BIT(29)
+
+#define	RMM_FEATURE_MIN_IPA_SIZE		32U
+#define RMM_FEATURE_REGISTER_0_INDEX		0UL
+#define RMM_FEATURE_REGISTER_0_S2SZ_SHIFT	0UL
+#define RMM_FEATURE_REGISTER_0_S2SZ_WIDTH	8UL
+#define RMM_FEATURE_REGISTER_0_LPA2_SHIFT	8UL
+#define RMM_FEATURE_REGISTER_0_LPA2_WIDTH	1UL
+
+/* RmiStatusCode types */
+/*
+ * Status codes which can be returned from RMM commands.
+ *
+ * For each code, the meaning of return_code_t::index is stated.
+ */
+typedef enum {
+	/*
+	 * Command completed successfully.
+	 *
+	 * index is zero.
+	 */
+	RMI_SUCCESS = 0,
+	/*
+	 * The value of a command input value caused the command to fail.
+	 *
+	 * index is zero.
+	 */
+	RMI_ERROR_INPUT = 1,
+	/*
+	 * An attribute of a Realm does not match the expected value.
+	 *
+	 * index varies between usages.
+	 */
+	RMI_ERROR_REALM = 2,
+	/*
+	 * An attribute of a REC does not match the expected value.
+	 *
+	 * index is zero.
+	 */
+	RMI_ERROR_REC = 3,
+	/*
+	 * An RTT walk terminated before reaching the target RTT level,
+	 * or reached an RTTE with an unexpected value.
+	 *
+	 * index: RTT level at which the walk terminated
+	 */
+	RMI_ERROR_RTT = 4,
+	/*
+	 * An operation cannot be completed because a resource is in use.
+	 *
+	 * index is zero.
+	 */
+	RMI_ERROR_IN_USE = 5,
+	RMI_ERROR_COUNT
+} status_t;
+
+#define RMI_RETURN_STATUS(ret)		((ret) & 0xFF)
+#define RMI_RETURN_INDEX(ret)		(((ret) >> 8U) & 0xFF)
+#define RTT_MAX_LEVEL			3U
+#define ALIGN_DOWN(x, a)		((uint64_t)(x) & ~(((uint64_t)(a)) - 1ULL))
+#define IS_ALIGNED(x, a)		(((x) & ((typeof(x))(a)-1U)) == 0U)
+#define PAGE_SHIFT			FOUR_KB_SHIFT
+#define RTT_LEVEL_SHIFT(l)		XLAT_ADDR_SHIFT(l)
+#define RTT_L2_BLOCK_SIZE		(1UL << RTT_LEVEL_SHIFT(2U))
+
+#define REC_CREATE_NR_GPRS		8U
+#define REC_HVC_NR_GPRS			7U
+#define REC_GIC_NUM_LRS			16U
+
+/*
+ * The error code 0x201 is the packed version of the
+ * rmm error {RMM_STATUS_ERROR_INPUT,2U}
+ * happened when Granule(params_ptr).pas != NS
+ */
+#define RMM_STATUS_ERROR_INPUT		0x201UL
+
+/*
+ * The Realm attribute parameters are shared by the Host via
+ * RMI_REALM_CREATE::params_ptr. The values can be observed or modified
+ * either by the Host or by the Realm.
+ */
+struct rmi_realm_params {
+	/* Realm feature register 0 */
+	SET_MEMBER(u_register_t features_0, 0, 0x100);		/* Offset 0 */
+	/* Measurement algorithm */
+	SET_MEMBER(unsigned char hash_algo, 0x100, 0x400);	/* 0x100 */
+	/* Realm Personalization Value */
+	SET_MEMBER(unsigned char rpv[RPV_SIZE], 0x400, 0x800);	/* 0x400 */
+	SET_MEMBER(struct {
+		/* Virtual Machine Identifier */
+		unsigned short vmid;				/* 0x800 */
+		/* Realm Translation Table base */
+		u_register_t rtt_base;				/* 0x808 */
+		/* RTT starting level */
+		long rtt_level_start;				/* 0x810 */
+		/* Number of starting level RTTs */
+		unsigned int rtt_num_start;			/* 0x818 */
+	}, 0x800, 0x1000);
+};
+
+/*
+ * The REC attribute parameters are shared by the Host via
+ * MI_REC_CREATE::params_ptr. The values can be observed or modified
+ * either by the Host or by the Realm which owns the REC.
+ */
+struct rmi_rec_params {
+	/* Flags */
+	SET_MEMBER(u_register_t flags, 0, 0x100);		/* Offset 0 */
+	/* MPIDR of the REC */
+	SET_MEMBER(u_register_t mpidr, 0x100, 0x200);		/* 0x100 */
+	/* Program counter */
+	SET_MEMBER(u_register_t pc, 0x200, 0x300);		/* 0x200 */
+	/* General-purpose registers */
+	SET_MEMBER(u_register_t gprs[REC_CREATE_NR_GPRS], 0x300, 0x800); /* 0x300 */
+	SET_MEMBER(struct {
+		/* Number of auxiliary Granules */
+		u_register_t num_aux;				/* 0x800 */
+		/* Addresses of auxiliary Granules */
+		u_register_t aux[MAX_REC_AUX_GRANULES];		/* 0x808 */
+	}, 0x800, 0x1000);
+};
+
+/*
+ * Structure contains data passed from the Host to the RMM on REC entry
+ */
+struct rmi_rec_entry {
+	/* Flags */
+	SET_MEMBER(u_register_t flags, 0, 0x200);		/* Offset 0 */
+	/* General-purpose registers */
+	SET_MEMBER(u_register_t gprs[REC_EXIT_NR_GPRS], 0x200, 0x300); /* 0x200 */
+	SET_MEMBER(struct {
+		/* GICv3 Hypervisor Control Register */
+		u_register_t gicv3_hcr;				/* 0x300 */
+		/* GICv3 List Registers */
+		u_register_t gicv3_lrs[REC_GIC_NUM_LRS];	/* 0x308 */
+	}, 0x300, 0x800);
+};
+
+/*
+ * Structure contains data passed from the RMM to the Host on REC exit
+ */
+struct rmi_rec_exit {
+	/* Exit reason */
+	SET_MEMBER(u_register_t exit_reason, 0, 0x100);/* Offset 0 */
+	SET_MEMBER(struct {
+		/* Exception Syndrome Register */
+		u_register_t esr;				/* 0x100 */
+		/* Fault Address Register */
+		u_register_t far;				/* 0x108 */
+		/* Hypervisor IPA Fault Address register */
+		u_register_t hpfar;				/* 0x110 */
+	}, 0x100, 0x200);
+	/* General-purpose registers */
+	SET_MEMBER(u_register_t gprs[REC_EXIT_NR_GPRS], 0x200, 0x300); /* 0x200 */
+	SET_MEMBER(struct {
+		/* GICv3 Hypervisor Control Register */
+		u_register_t gicv3_hcr;				/* 0x300 */
+		/* GICv3 List Registers */
+		u_register_t gicv3_lrs[REC_GIC_NUM_LRS];	/* 0x308 */
+		/* GICv3 Maintenance Interrupt State Register */
+		u_register_t gicv3_misr;			/* 0x388 */
+		/* GICv3 Virtual Machine Control Register */
+		u_register_t gicv3_vmcr;			/* 0x390 */
+	}, 0x300, 0x400);
+	SET_MEMBER(struct {
+		/* Counter-timer Physical Timer Control Register */
+		u_register_t cntp_ctl;				/* 0x400 */
+		/* Counter-timer Physical Timer CompareValue Register */
+		u_register_t cntp_cval;				/* 0x408 */
+		/* Counter-timer Virtual Timer Control Register */
+		u_register_t cntv_ctl;				/* 0x410 */
+		/* Counter-timer Virtual Timer CompareValue Register */
+		u_register_t cntv_cval;				/* 0x418 */
+	}, 0x400, 0x500);
+	SET_MEMBER(struct {
+		/* Base address of pending RIPAS change */
+		u_register_t ripas_base;			/* 0x500 */
+		/* Size of pending RIPAS change */
+		u_register_t ripas_size;			/* 0x508 */
+		/* RIPAS value of pending RIPAS change */
+		unsigned char ripas_value;			/* 0x510 */
+	}, 0x500, 0x600);
+	/* Host call immediate value */
+	SET_MEMBER(unsigned int imm, 0x600, 0x800);		/* 0x600 */
+};
+
+/*
+ * Structure contains shared information between RMM and Host
+ * during REC entry and REC exit.
+ */
+struct rmi_rec_run {
+	/* Entry information */
+	SET_MEMBER(struct rmi_rec_entry entry, 0, 0x800);	/* Offset 0 */
+	/* Exit information */
+	SET_MEMBER(struct rmi_rec_exit exit, 0x800, 0x1000);	/* 0x800 */
+};
+
+struct rtt_entry {
+	uint64_t walk_level;
+	uint64_t out_addr;
+	int state;
+};
+
+enum realm_state {
+	REALM_STATE_NULL,
+	REALM_STATE_NEW,
+	REALM_STATE_ACTIVE,
+	REALM_STATE_SYSTEM_OFF
+};
+
+struct realm {
+	u_register_t par_base;
+	u_register_t par_size;
+	u_register_t rd;
+	u_register_t rtt_addr;
+	u_register_t rec;
+	u_register_t run;
+	u_register_t num_aux;
+	u_register_t rmm_feat_reg0;
+	u_register_t ipa_ns_buffer;
+	u_register_t ns_buffer_size;
+	u_register_t aux_pages[REC_PARAMS_AUX_GRANULES];
+	enum realm_state state;
+};
+
+/* RMI/SMC */
+u_register_t rmi_version(void);
+u_register_t rmi_granule_delegate(u_register_t addr);
+u_register_t rmi_granule_undelegate(u_register_t addr);
+u_register_t rmi_realm_create(u_register_t rd, u_register_t params_ptr);
+u_register_t rmi_realm_destroy(u_register_t rd);
+u_register_t rmi_features(u_register_t index, u_register_t *features);
+
+/* Realm management */
+u_register_t realm_map_protected_data_unknown(struct realm *realm,
+		u_register_t target_pa,
+		u_register_t map_size);
+u_register_t realm_create(struct realm *realm);
+u_register_t realm_map_payload_image(struct realm *realm,
+		u_register_t realm_payload_adr);
+u_register_t realm_map_ns_shared(struct realm *realm,
+		u_register_t ns_shared_mem_adr,
+		u_register_t ns_shared_mem_size);
+u_register_t realm_rec_create(struct realm *realm);
+u_register_t realm_activate(struct realm *realm);
+u_register_t realm_destroy(struct realm *realm);
+u_register_t realm_rec_enter(struct realm *realm, u_register_t *exit_reason,
+		unsigned int *test_result);
+u_register_t realm_init_ipa_state(struct realm *realm,
+		u_register_t  level,
+		u_register_t  start,
+		uint64_t  end);
+
+
+#endif /* HOST_REALM_RMI_H */
diff --git a/include/runtime_services/host_realm_managment/host_shared_data.h b/include/runtime_services/host_realm_managment/host_shared_data.h
new file mode 100644
index 0000000..9c9cc8c
--- /dev/null
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef HOST_SHARED_DATA_H
+#define HOST_SHARED_DATA_H
+
+#include <stdint.h>
+#include <spinlock.h>
+
+#define MAX_BUF_SIZE		10240U
+#define MAX_DATA_SIZE		5U
+
+/*
+ * This structure maps the shared memory to be used between the Host and Realm
+ * payload
+ */
+typedef struct host_shared_data {
+	/* Buffer used from Realm for logging*/
+	uint8_t log_buffer[MAX_BUF_SIZE];
+
+	/* Command set from Host and used by Realm*/
+	uint8_t realm_cmd;
+
+	/* array of params passed from Host to Realm*/
+	u_register_t host_param_val[MAX_DATA_SIZE];
+
+	/* array of output results passed from Realm to Host*/
+	u_register_t realm_out_val[MAX_DATA_SIZE];
+
+	/* Lock to avoid concurrent accesses to log_buffer */
+	spinlock_t printf_lock;
+} host_shared_data_t;
+
+/*
+ * Different commands that the Host can requests the Realm to perform
+ */
+enum realm_cmd {
+	REALM_SLEEP_CMD = 1U,
+	REALM_GET_RSI_VERSION
+};
+
+/*
+ * Index values for each parameter in the host_param_val array.
+ */
+enum host_param_index {
+	HOST_CMD_INDEX = 0U,
+	HOST_SLEEP_INDEX
+};
+/*
+ * Return shared buffer pointer mapped as host_shared_data_t structure
+ */
+host_shared_data_t *host_get_shared_structure(void);
+/*
+ * Set data to be shared from Host to realm
+ */
+void realm_shared_data_set_host_val(uint8_t index, u_register_t val);
+
+/*
+ * Set guest mapped shared buffer pointer
+ */
+void realm_set_shared_structure(host_shared_data_t *ptr);
+
+/*
+ * Get guest mapped shared buffer pointer
+ */
+host_shared_data_t *realm_get_shared_structure(void);
+
+/*
+ * Set data to be shared from Realm to Host
+ */
+void realm_shared_data_set_realm_val(uint8_t index, u_register_t val);
+
+/*
+ * Return Host's data at index
+ */
+u_register_t realm_shared_data_get_host_val(uint8_t index);
+
+/*
+ * Return Realm's data at index
+ */
+u_register_t realm_shared_data_get_realm_val(uint8_t index);
+
+/*
+ * Clear shared realm data
+ */
+void realm_shared_data_clear_realm_val(void);
+
+/*
+ * Clear shared Host data
+ */
+void realm_shared_data_clear_host_val(void);
+
+/*
+ * Get command sent from Host to realm
+ */
+uint8_t realm_shared_data_get_realm_cmd(void);
+
+/*
+ * Set command to be send from Host to realm
+ */
+void realm_shared_data_set_realm_cmd(uint8_t cmd);
+
+#endif /* HOST_SHARED_DATA_H */
diff --git a/include/runtime_services/host_realm_managment/realm_def.h b/include/runtime_services/host_realm_managment/realm_def.h
new file mode 100644
index 0000000..22cd380
--- /dev/null
+++ b/include/runtime_services/host_realm_managment/realm_def.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef REALM_DEF_H
+#define REALM_DEF_H
+
+#include <xlat_tables_defs.h>
+
+/* 1mb for Realm payload as a default value*/
+#define REALM_MAX_LOAD_IMG_SIZE		U(0x100000)
+#define REALM_STACK_SIZE		0x1000U
+#define DATA_PATTERN_1			0x12345678U
+#define DATA_PATTERN_2			0x11223344U
+#define REALM_SUCCESS			0U
+#define REALM_ERROR			1U
+
+/* Only support 4KB at the moment */
+
+#if (PAGE_SIZE == PAGE_SIZE_4KB)
+#define PAGE_ALIGNMENT			PAGE_SIZE_4KB
+#define TCR_TG0				TCR_TG0_4K
+#else
+#error "Undefined value for PAGE_SIZE"
+#endif
+
+#endif /* REALM_DEF_H */
diff --git a/include/runtime_services/host_realm_managment/rmi_spm_tests.h b/include/runtime_services/host_realm_managment/rmi_spm_tests.h
new file mode 100644
index 0000000..11c8c12
--- /dev/null
+++ b/include/runtime_services/host_realm_managment/rmi_spm_tests.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef REALM_PAYLOAD_TEST_H
+#define REALM_PAYLOAD_TEST_H
+
+#define NUM_GRANULES			5U
+#define NUM_RANDOM_ITERATIONS		7U
+#define B_DELEGATED			0U
+#define B_UNDELEGATED			1U
+#define NUM_CPU_DED_SPM			PLATFORM_CORE_COUNT / 2U
+
+#endif /* REALM_PAYLOAD_TEST_H */
diff --git a/include/runtime_services/realm_payload/realm_payload_test.h b/include/runtime_services/realm_payload/realm_payload_test.h
deleted file mode 100644
index 048dda1..0000000
--- a/include/runtime_services/realm_payload/realm_payload_test.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <smccc.h>
-#include <tftf_lib.h>
-
-#define RMI_FNUM_MIN_VALUE	U(0x150)
-#define RMI_FNUM_MAX_VALUE	U(0x18F)
-
-/* Get RMI fastcall std FID from offset */
-#define SMC64_RMI_FID(_offset)					  \
-	((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT)			| \
-	 (SMC_64 << FUNCID_CC_SHIFT)				| \
-	 (OEN_STD_START << FUNCID_OEN_SHIFT)			| \
-	 (((RMI_FNUM_MIN_VALUE + (_offset)) & FUNCID_NUM_MASK)	  \
-	  << FUNCID_NUM_SHIFT))
-
-/* RMI SMC64 FIDs handled by the RMMD */
-#define RMI_RMM_REQ_VERSION		SMC64_RMI_FID(U(0))
-#define SMC_RMM_GRANULE_DELEGATE	SMC64_RMI_FID(U(1))
-#define SMC_RMM_GRANULE_UNDELEGATE	SMC64_RMI_FID(U(2))
-#define SMC_RMM_REALM_CREATE		SMC64_RMI_FID(U(8))
-#define SMC_RMM_REALM_DESTROY		SMC64_RMI_FID(U(9))
-
-#define RMI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16)
-#define RMI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF)
-
-#define NUM_GRANULES			5
-#define NUM_RANDOM_ITERATIONS		7
-#define GRANULE_SIZE			4096
-
-#define B_DELEGATED			0
-#define B_UNDELEGATED			1
-
-#define NUM_CPU_DED_SPM			PLATFORM_CORE_COUNT / 2
-/*
- * The error code 513 is the packed version of the
- * rmm error {RMM_STATUS_ERROR_INPUT,2}
- * happened when Granule(params_ptr).pas != NS
- */
-#define RMM_STATUS_ERROR_INPUT		513UL
-u_register_t realm_version(void);
-u_register_t realm_granule_delegate(uintptr_t);
-u_register_t realm_granule_undelegate(uintptr_t);
-u_register_t realm_create(uintptr_t, uintptr_t);
-u_register_t realm_destroy(uintptr_t);
\ No newline at end of file
diff --git a/lib/heap/page_alloc.c b/lib/heap/page_alloc.c
new file mode 100644
index 0000000..c1b54c8
--- /dev/null
+++ b/lib/heap/page_alloc.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <debug.h>
+#include <heap/page_alloc.h>
+#include <spinlock.h>
+#include <utils_def.h>
+
+#include <platform_def.h>
+
+static uint64_t memory_used;
+static uint64_t heap_base_addr;
+static u_register_t heap_addr;
+static uint64_t heap_size;
+static bool heap_initialised = HEAP_INIT_FAILED;
+static spinlock_t mem_lock;
+
+/*
+ * Initialize the memory heap space to be used
+ * @heap_base: heap base address
+ * @heap_len: heap size for use
+ */
+int page_pool_init(uint64_t heap_base, uint64_t heap_len)
+{
+	const uint64_t plat_max_addr = (uint64_t)DRAM_BASE + (uint64_t)DRAM_SIZE;
+	uint64_t max_addr = heap_base + heap_len;
+
+	if (heap_len == 0ULL) {
+		ERROR("heap_len must be non-zero value\n");
+		heap_initialised = HEAP_INVALID_LEN;
+	} else if (max_addr >= plat_max_addr) {
+		ERROR("heap_base + heap[0x%llx] must not exceed platform"
+			"max address[0x%llx]\n", max_addr, plat_max_addr);
+
+		heap_initialised = HEAP_OUT_OF_RANGE;
+	} else {
+		heap_base_addr = heap_base;
+		memory_used = heap_base;
+		heap_size = heap_len;
+		heap_initialised = HEAP_INIT_SUCCESS;
+	}
+	return heap_initialised;
+}
+
+/*
+ * Return the pointer to the allocated pages
+ * @bytes_size: pages to allocate in byte unit
+ */
+void *page_alloc(u_register_t bytes_size)
+{
+	if (heap_initialised != HEAP_INIT_SUCCESS) {
+		ERROR("heap need to be initialised first\n");
+		return HEAP_NULL_PTR;
+	}
+	if (bytes_size == 0UL) {
+		ERROR("bytes_size must be non-zero value\n");
+		return HEAP_NULL_PTR;
+	}
+
+	spin_lock(&mem_lock);
+
+	if ((memory_used + bytes_size) >= (heap_base_addr + heap_size)) {
+		ERROR("Reached to max KB allowed[%llu]\n", (heap_size/1024U));
+		goto unlock_failed;
+	}
+	/* set pointer to current used heap memory cursor */
+	heap_addr = memory_used;
+	/* move used memory cursor by bytes_size */
+	memory_used += bytes_size;
+	spin_unlock(&mem_lock);
+
+	return (void *)heap_addr;
+
+unlock_failed:/* failed allocation */
+	spin_unlock(&mem_lock);
+	return HEAP_NULL_PTR;
+}
+
+/*
+ * Reset heap memory usage cursor to heap base address
+ */
+void page_pool_reset(void)
+{
+	/*
+	 * No race condition here, only lead cpu running TFTF test case can
+	 * reset the memory allocation
+	 */
+	memory_used = heap_base_addr;
+}
+
+void page_free(u_register_t address)
+{
+	/* No memory free is needed in current TFTF test scenarios */
+}
diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c
index 29c50df..6ad284f 100644
--- a/lib/libc/snprintf.c
+++ b/lib/libc/snprintf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,6 @@
 #include <stdlib.h>
 
 #include <common/debug.h>
-#include <plat/common/platform.h>
 
 #define get_num_va_args(_args, _lcount)				\
 	(((_lcount) > 1)  ? va_arg(_args, long long int) :	\
diff --git a/plat/arm/fvp/platform.mk b/plat/arm/fvp/platform.mk
index e467cd6..cb1a37b 100644
--- a/plat/arm/fvp/platform.mk
+++ b/plat/arm/fvp/platform.mk
@@ -1,9 +1,12 @@
 #
-# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# If not specified as build arguments, set default to 10 MB
+TFTF_MAX_IMAGE_SIZE:=10485760
+
 # Default number of threads per CPU on FVP
 FVP_MAX_PE_PER_CPU		:= 1
 
@@ -79,6 +82,7 @@
 $(eval $(call add_define,TFTF_DEFINES,FVP_CLUSTER_COUNT))
 $(eval $(call add_define,TFTF_DEFINES,FVP_MAX_CPUS_PER_CLUSTER))
 $(eval $(call add_define,TFTF_DEFINES,FVP_MAX_PE_PER_CPU))
+$(eval $(call add_define,TFTF_DEFINES,TFTF_MAX_IMAGE_SIZE))
 
 # Default PA size for FVP platform
 PA_SIZE := 34
@@ -88,6 +92,7 @@
 $(eval $(call add_define,NS_BL1U_DEFINES,PA_SIZE))
 $(eval $(call add_define,NS_BL2U_DEFINES,PA_SIZE))
 $(eval $(call add_define,TFTF_DEFINES,PA_SIZE))
+$(eval $(call add_define,REALM_DEFINES,PA_SIZE))
 
 PLAT_INCLUDES	+=	-Iplat/arm/fvp/include/
 
diff --git a/realm/aarch64/realm_entrypoint.S b/realm/aarch64/realm_entrypoint.S
new file mode 100644
index 0000000..97c4ff5
--- /dev/null
+++ b/realm/aarch64/realm_entrypoint.S
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <realm_def.h>
+
+	.globl	realm_entrypoint
+
+.section .bss.stacks
+	.fill	REALM_STACK_SIZE
+stacks_end:
+
+func realm_entrypoint
+	/* Setup the stack pointer. */
+	adr	x1, stacks_end
+	mov	sp, x1
+
+	/* Clear BSS */
+	ldr	x0, =__REALM_BSS_START__
+	adr	x1, realm_entrypoint
+	add	x0, x1, x0
+	ldr	x1, =__REALM_BSS_SIZE__
+	bl	zeromem16
+
+	/*
+	 * Invalidate the data cache for the whole Realm.
+	 * This prevents re-use of stale data cache entries from
+	 * prior bootloader stages.
+	 */
+	adrp	x0, __REALM_TEXT_START__
+	add	x0, x0, realm_entrypoint
+	adrp	x1, __REALM_BSS_END__
+	add	x1, x1, realm_entrypoint
+	sub	x1, x1, x0
+	bl	inv_dcache_range
+
+	/* Initialize architectural state. */
+	bl	arch_init
+
+	/* Relocate symbols */
+pie_fixup:
+	ldr	x0, =pie_fixup
+	and	x0, x0, #~(PAGE_ALIGNMENT - 1)
+	mov	x1, REALM_MAX_LOAD_IMG_SIZE
+	add	x1, x1, x0
+	bl	fixup_gdt_reloc
+
+	/* And jump to the C entrypoint. */
+	b	realm_payload_main
+endfunc realm_entrypoint
+
+/* Initialize architectural state. */
+func arch_init
+	/* Set the exception vectors. */
+	adr	x0, realm_vector
+	add	x1, x1, :lo12:realm_vector
+	msr	vbar_el1, x0
+	isb
+
+	/* Enable the instruction cache and stack pointer alignment checks. */
+	mov_imm	x0, (SCTLR_EL1_RES1 | SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+	msr	sctlr_el1, x0
+
+	/*
+	 * Set CPACR_EL1.FPEN=11 no EL1/0 trapping of
+	 * SVE/Adv. SIMD/FP instructions.
+	 */
+	mov	x1, CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE)
+	mrs	x0, cpacr_el1
+	orr	x0, x0, x1
+	msr	cpacr_el1, x0
+	isb
+
+	ret
+endfunc arch_init
diff --git a/realm/aarch64/realm_exceptions.S b/realm/aarch64/realm_exceptions.S
new file mode 100644
index 0000000..6ce8810
--- /dev/null
+++ b/realm/aarch64/realm_exceptions.S
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+	.globl	realm_vector
+
+/*
+ * Exception vector code for unhandled exceptions.
+ * Print a crash dump on the UART and loops forever.
+ */
+.macro unhandled_exception name
+	vector_entry \name
+	b crash_dump
+	end_vector_entry \name
+.endm
+
+vector_base realm_vector
+
+	/*
+	 * Current EL with SP0 : 0x0 - 0x200.
+	 */
+unhandled_exception sync_sp0
+unhandled_exception irq_sp0
+unhandled_exception fiq_sp0
+unhandled_exception serr_sp0
+
+	/*
+	 * Current EL with SPx : 0x200 - 0x400.
+	 */
+vector_entry sync_spx
+	b	sync_exception_vector_entry
+end_vector_entry sync_spx
+
+vector_entry irq_spx
+	b	interrupt_vector_entry
+end_vector_entry irq_spx
+
+vector_entry fiq_spx
+	b	interrupt_vector_entry
+end_vector_entry fiq_spx
+
+unhandled_exception serr_spx
+
+	/*
+	 * Lower EL using AArch64 : 0x400 - 0x600.
+	 */
+unhandled_exception sync_a64
+unhandled_exception irq_a64
+unhandled_exception fiq_a64
+unhandled_exception serr_a64
+
+	/*
+	 * Lower EL using AArch32 : 0x600 - 0x800.
+	 */
+unhandled_exception sync_a32
+unhandled_exception irq_a32
+unhandled_exception fiq_a32
+unhandled_exception serr_a32
+
+.macro save_gp_regs
+	stp	x0, x1, [sp, #0x0]
+	stp	x2, x3, [sp, #0x10]
+	stp	x4, x5, [sp, #0x20]
+	stp	x6, x7, [sp, #0x30]
+	stp	x8, x9, [sp, #0x40]
+	stp	x10, x11, [sp, #0x50]
+	stp	x12, x13, [sp, #0x60]
+	stp	x14, x15, [sp, #0x70]
+	stp	x16, x17, [sp, #0x80]
+	stp	x18, x19, [sp, #0x90]
+	stp	x20, x21, [sp, #0xa0]
+	stp	x22, x23, [sp, #0xb0]
+	stp	x24, x25, [sp, #0xc0]
+	stp	x26, x27, [sp, #0xd0]
+	stp	x28, x29, [sp, #0xe0]
+	/* We push xzr simply to keep the stack 16-byte aligned. */
+	stp	x30, xzr, [sp, #0xf0]
+.endm
+
+.macro restore_gp_regs
+	ldp	x30, xzr, [sp, #0xf0]
+	ldp	x28, x29, [sp, #0xe0]
+	ldp	x26, x27, [sp, #0xd0]
+	ldp	x24, x25, [sp, #0xc0]
+	ldp	x22, x23, [sp, #0xb0]
+	ldp	x20, x21, [sp, #0xa0]
+	ldp	x18, x19, [sp, #0x90]
+	ldp	x16, x17, [sp, #0x80]
+	ldp	x14, x15, [sp, #0x70]
+	ldp	x12, x13, [sp, #0x60]
+	ldp	x10, x11, [sp, #0x50]
+	ldp	x8, x9, [sp, #0x40]
+	ldp	x6, x7, [sp, #0x30]
+	ldp	x4, x5, [sp, #0x20]
+	ldp	x2, x3, [sp, #0x10]
+	ldp	x0, x1, [sp, #0x0]
+.endm
+
+func sync_exception_vector_entry
+	sub	sp, sp, #0x100
+	save_gp_regs
+	mov	x19, sp
+	bl	tftf_sync_exception_handler
+	cbnz	x0, 0f
+	mov x0, x19
+	/* Save original stack pointer value on the stack */
+	add	x1, x0, #0x100
+	str	x1, [x0, #0xf8]
+	b print_exception
+0:	restore_gp_regs
+	add	sp, sp, #0x100
+	eret
+endfunc sync_exception_vector_entry
+
+func interrupt_vector_entry
+	sub	sp, sp, #0x100
+	save_gp_regs
+	bl	realm_interrupt_handler
+	restore_gp_regs
+	add	sp, sp, #0x100
+	eret
+endfunc interrupt_vector_entry
+
+func crash_dump
+	/* Save general-purpose registers on the stack. */
+	sub	sp, sp, #0x100
+	save_gp_regs
+
+	/* Save original stack pointer value on the stack. */
+	add	x1, sp, #0x100
+	str	x1, [sp, #0xf8]
+
+	/* Print the saved CPU context on the UART. */
+	mov	x0, sp
+	b	print_exception
+endfunc crash_dump
diff --git a/realm/platform.h b/realm/platform.h
new file mode 100644
index 0000000..2c6ad27
--- /dev/null
+++ b/realm/platform.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef REALM_PLATFORM_H
+#define REALM_PLATFORM_H
+
+/*
+ * Helper that returns a linear core ID from a MPID
+ * Need to provide a RSI_HOST_CALL to request this from Host platform.
+ */
+unsigned int platform_get_core_pos(u_register_t mpid)
+{
+	return 0U;
+}
+
+#endif /* REALM_PLATFORM_H */
diff --git a/realm/realm.ld.S b/realm/realm.ld.S
new file mode 100644
index 0000000..ca3b809
--- /dev/null
+++ b/realm/realm.ld.S
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+ENTRY(realm_entrypoint)
+
+#include <realm_def.h>
+
+MEMORY {
+
+    RAM (rwx): ORIGIN = 0x0, LENGTH = REALM_MAX_LOAD_IMG_SIZE
+}
+
+SECTIONS
+{
+     ASSERT(. == ALIGN(PAGE_SIZE),
+           "TEXT_START address is not aligned to PAGE_SIZE.")
+    .text : {
+        __REALM_TEXT_START__ = .;
+        *realm_entrypoint.o(.text*)
+        *(.text*)
+        *(.vectors)
+        . = NEXT(PAGE_SIZE);
+        __REALM_TEXT_END__ = .;
+    }> RAM
+
+    .rodata : {
+        . = ALIGN(PAGE_SIZE);
+        __REALM_RODATA_START__ = .;
+        *(.rodata*)
+
+        /*
+         * Keep the .got section in the RO section as it is patched
+         * prior to enabling the MMU and having the .got in RO is better for
+         * security. GOT is a table of addresses so ensure 8-byte alignment.
+         */
+        . = ALIGN(8);
+        __GOT_START__ = .;
+        *(.got)
+        __GOT_END__ = .;
+
+        . = NEXT(PAGE_SIZE);
+        __REALM_RODATA_END__ = .;
+
+    }> RAM
+
+    .data : {
+        . = ALIGN(PAGE_SIZE);
+        __REALM_DATA_START__ = .;
+        *(.data*)
+        . = ALIGN(PAGE_SIZE);
+        . = NEXT(PAGE_SIZE);
+        __REALM_DATA_END__ = .;
+    }> RAM
+
+    /*
+     * .rela.dyn needs to come after .data for the read-elf utility to parse
+     * this section correctly. Ensure 8-byte alignment so that the fields of
+     * RELA data structure are aligned.
+     */
+    . = ALIGN(8);
+    __RELA_START__ = .;
+    .rela.dyn . : {
+    }> RAM
+    __RELA_END__ = .;
+
+    .bss (NOLOAD) : {
+        . = ALIGN(PAGE_SIZE);
+        __REALM_BSS_START__ = .;
+        *(SORT_BY_ALIGNMENT(.bss*))
+        *(COMMON)
+        . = NEXT(PAGE_SIZE);
+        __REALM_BSS_END__ = .;
+    }> RAM
+    __REALM_BSS_SIZE__ = SIZEOF(.bss);
+}
diff --git a/realm/realm.mk b/realm/realm.mk
new file mode 100644
index 0000000..638f02e
--- /dev/null
+++ b/realm/realm.mk
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include branch_protection.mk
+
+REALM_INCLUDES :=							\
+	-Itftf/framework/include					\
+	-Iinclude							\
+	-Iinclude/common						\
+	-Iinclude/common/${ARCH}					\
+	-Iinclude/lib							\
+	-Iinclude/lib/${ARCH}						\
+	-Iinclude/lib/utils						\
+	-Iinclude/lib/xlat_tables					\
+	-Iinclude/runtime_services					\
+	-Iinclude/runtime_services/host_realm_managment			\
+	-Irealm								\
+	-Irealm/aarch64
+
+REALM_SOURCES:=								\
+	$(addprefix realm/,						\
+	aarch64/realm_entrypoint.S					\
+	aarch64/realm_exceptions.S					\
+	realm_debug.c							\
+	realm_payload_main.c						\
+	realm_interrupt.c						\
+	realm_rsi.c							\
+	realm_shared_data.c						\
+	)
+
+REALM_SOURCES += lib/${ARCH}/cache_helpers.S				\
+	lib/${ARCH}/misc_helpers.S					\
+	lib/smc/${ARCH}/asm_smc.S					\
+	lib/smc/${ARCH}/smc.c						\
+	lib/exceptions/${ARCH}/sync.c					\
+	lib/locks/${ARCH}/spinlock.S					\
+	lib/delay/delay.c
+
+# TODO: Remove dependency on TFTF files.
+REALM_SOURCES	+=							\
+	tftf/framework/${ARCH}/exception_report.c
+
+REALM_LINKERFILE:=	realm/realm.ld.S
+
+REALM_DEFINES:=
+$(eval $(call add_define,REALM_DEFINES,ARM_ARCH_MAJOR))
+$(eval $(call add_define,REALM_DEFINES,ARM_ARCH_MINOR))
+$(eval $(call add_define,REALM_DEFINES,ENABLE_BTI))
+$(eval $(call add_define,REALM_DEFINES,ENABLE_PAUTH))
+$(eval $(call add_define,REALM_DEFINES,LOG_LEVEL))
+$(eval $(call add_define,REALM_DEFINES,IMAGE_REALM))
diff --git a/realm/realm_debug.c b/realm/realm_debug.c
new file mode 100644
index 0000000..e9eb61e
--- /dev/null
+++ b/realm/realm_debug.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <host_shared_data.h>
+
+/*
+ * A printf formatted function used in the Realm world to log messages
+ * in the shared buffer.
+ * Locate the shared logging buffer and print its content
+ */
+void realm_printf(const char *fmt, ...)
+{
+	host_shared_data_t *guest_shared_data = realm_get_shared_structure();
+	char *log_buffer = (char *)guest_shared_data->log_buffer;
+	va_list args;
+
+	va_start(args, fmt);
+	spin_lock((spinlock_t *)&guest_shared_data->printf_lock);
+	if (strnlen((const char *)log_buffer, MAX_BUF_SIZE) == MAX_BUF_SIZE) {
+		(void)memset((char *)log_buffer, 0, MAX_BUF_SIZE);
+	}
+	(void)vsnprintf((char *)log_buffer +
+			strnlen((const char *)log_buffer, MAX_BUF_SIZE),
+			MAX_BUF_SIZE, fmt, args);
+	spin_unlock((spinlock_t *)&guest_shared_data->printf_lock);
+	va_end(args);
+}
+
+void __attribute__((__noreturn__)) do_panic(const char *file, int line)
+{
+	realm_printf("PANIC in file: %s line: %d\n", file, line);
+	while (true) {
+		continue;
+	}
+}
+
+/* This is used from printf() when crash dump is reached */
+int console_putc(int c)
+{
+	host_shared_data_t *guest_shared_data = realm_get_shared_structure();
+	char *log_buffer = (char *)guest_shared_data->log_buffer;
+
+	if ((c < 0) || (c > 127)) {
+		return -1;
+	}
+	spin_lock((spinlock_t *)&guest_shared_data->printf_lock);
+	if (strnlen((const char *)log_buffer, MAX_BUF_SIZE) == MAX_BUF_SIZE) {
+		(void)memset((char *)log_buffer, 0, MAX_BUF_SIZE);
+	}
+	*((char *)log_buffer + strnlen((const char *)log_buffer, MAX_BUF_SIZE)) = c;
+	spin_unlock((spinlock_t *)&guest_shared_data->printf_lock);
+
+	return c;
+}
diff --git a/realm/realm_interrupt.c b/realm/realm_interrupt.c
new file mode 100644
index 0000000..02ab55c
--- /dev/null
+++ b/realm/realm_interrupt.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+
+/* dummy interrupt handler as for now*/
+void realm_interrupt_handler(void)
+{
+	INFO("%s\n", __func__);
+}
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
new file mode 100644
index 0000000..bd4dec7
--- /dev/null
+++ b/realm/realm_payload_main.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdio.h>
+
+#include <debug.h>
+#include <host_realm_helper.h>
+#include <host_shared_data.h>
+#include "realm_def.h"
+#include <realm_rsi.h>
+#include <tftf_lib.h>
+
+/*
+ * This function reads sleep time in ms from shared buffer and spins PE in a loop
+ * for that time period.
+ */
+static void realm_sleep_cmd(void)
+{
+	uint64_t sleep = realm_shared_data_get_host_val(HOST_SLEEP_INDEX);
+
+	INFO("REALM_PAYLOAD: Realm payload going to sleep for %llums\n", sleep);
+	waitms(sleep);
+}
+
+/*
+ * This function requests RSI/ABI version from RMM.
+ */
+static void realm_get_rsi_version(void)
+{
+	u_register_t version;
+
+	version = rsi_get_version();
+	if (version == (u_register_t)SMC_UNKNOWN) {
+		ERROR("SMC_RSI_ABI_VERSION failed (%ld)", (long)version);
+		return;
+	}
+
+	INFO("RSI ABI version %u.%u (expected: %u.%u)",
+	RSI_ABI_VERSION_GET_MAJOR(version),
+	RSI_ABI_VERSION_GET_MINOR(version),
+	RSI_ABI_VERSION_GET_MAJOR(RSI_ABI_VERSION),
+	RSI_ABI_VERSION_GET_MINOR(RSI_ABI_VERSION));
+}
+
+/*
+ * This is the entry function for Realm payload, it first requests the shared buffer
+ * IPA address from Host using HOST_CALL/RSI, it reads the command to be executed,
+ * performs the request, and returns to Host with the execution state SUCCESS/FAILED
+ *
+ * Host in NS world requests Realm to execute certain operations using command
+ * depending on the test case the Host wants to perform.
+ */
+void realm_payload_main(void)
+{
+	uint8_t cmd = 0U;
+	bool test_succeed = false;
+
+	realm_set_shared_structure((host_shared_data_t *)rsi_get_ns_buffer());
+	if (realm_get_shared_structure() != NULL) {
+		cmd = realm_shared_data_get_realm_cmd();
+		switch (cmd) {
+		case REALM_SLEEP_CMD:
+			realm_sleep_cmd();
+			test_succeed = true;
+			break;
+		case REALM_GET_RSI_VERSION:
+			realm_get_rsi_version();
+			test_succeed = true;
+			break;
+		default:
+			INFO("REALM_PAYLOAD: %s invalid cmd=%hhu", __func__, cmd);
+			break;
+		}
+	}
+
+	if (test_succeed) {
+		rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
+	} else {
+		rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+	}
+}
diff --git a/realm/realm_rsi.c b/realm/realm_rsi.c
new file mode 100644
index 0000000..c805514
--- /dev/null
+++ b/realm/realm_rsi.c
@@ -0,0 +1,47 @@
+
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <host_realm_rmi.h>
+#include <lib/aarch64/arch_features.h>
+#include <realm_rsi.h>
+#include <smccc.h>
+
+static struct rsi_host_call host_cal __aligned(sizeof(struct rsi_host_call));
+
+/* This function return RSI_ABI_VERSION */
+u_register_t rsi_get_version(void)
+{
+	smc_ret_values res = {};
+
+	res = tftf_smc(&(smc_args)
+		{RSI_ABI_VERSION, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+
+	return res.ret0;
+}
+
+/* This function will call the Host to request IPA of the NS shared buffer */
+u_register_t rsi_get_ns_buffer(void)
+{
+	smc_ret_values res = {};
+
+	host_cal.imm = HOST_CALL_GET_SHARED_BUFF_CMD;
+	res = tftf_smc(&(smc_args) {RSI_HOST_CALL, (u_register_t)&host_cal,
+		0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+	if (res.ret0 != RSI_SUCCESS) {
+		return 0U;
+	}
+	return host_cal.gprs[0];
+}
+
+/* This function call Host and request to exit Realm with proper exit code */
+void rsi_exit_to_host(enum host_call_cmd exit_code)
+{
+	host_cal.imm = exit_code;
+	tftf_smc(&(smc_args) {RSI_HOST_CALL, (u_register_t)&host_cal,
+		0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+}
diff --git a/realm/realm_rsi.h b/realm/realm_rsi.h
new file mode 100644
index 0000000..34721cd
--- /dev/null
+++ b/realm/realm_rsi.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef REALM_RSI_H
+#define REALM_RSI_H
+
+#include <stdint.h>
+#include <tftf_lib.h>
+
+#define SMC_RSI_CALL_BASE	0xC4000190
+#define SMC_RSI_FID(_x)		(SMC_RSI_CALL_BASE + (_x))
+/*
+ * This file describes the Realm Services Interface (RSI) Application Binary
+ * Interface (ABI) for SMC calls made from within the Realm to the RMM and
+ * serviced by the RMM.
+ *
+ * See doc/rmm_interface.md for more details.
+ */
+
+/*
+ * The major version number of the RSI implementation.  Increase this whenever
+ * the binary format or semantics of the SMC calls change.
+ */
+#define RSI_ABI_VERSION_MAJOR		12U
+
+/*
+ * The minor version number of the RSI implementation.  Increase this when
+ * a bug is fixed, or a feature is added without breaking binary compatibility.
+ */
+#define RSI_ABI_VERSION_MINOR		0U
+
+#define RSI_ABI_VERSION_VAL		((RSI_ABI_VERSION_MAJOR << 16U) | \
+					 RSI_ABI_VERSION_MINOR)
+
+#define RSI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16U)
+#define RSI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFFU)
+
+
+/* RSI Status code enumeration as per Section D4.3.6 of the RMM Spec */
+typedef enum {
+	/* Command completed successfully */
+	RSI_SUCCESS = 0U,
+
+	/*
+	 * The value of a command input value
+	 * caused the command to fail
+	 */
+	RSI_ERROR_INPUT	= 1U,
+
+	/*
+	 * The state of the current Realm or current REC
+	 * does not match the state expected by the command
+	 */
+	RSI_ERROR_STATE	= 2U,
+
+	/* The operation requested by the command is not complete */
+	RSI_INCOMPLETE = 3U,
+
+	RSI_ERROR_COUNT
+} rsi_status_t;
+
+enum host_call_cmd {
+	HOST_CALL_GET_SHARED_BUFF_CMD = 1U,
+	HOST_CALL_EXIT_SUCCESS_CMD,
+	HOST_CALL_EXIT_FAILED_CMD
+};
+
+struct rsi_realm_config {
+	/* IPA width in bits */
+	SET_MEMBER(unsigned long ipa_width, 0, 0x1000);	/* Offset 0 */
+};
+
+/*
+ * arg0 == IPA address of target region
+ * arg1 == Size of target region in bytes
+ * arg2 == RIPAS value
+ * ret0 == Status / error
+ * ret1 == Top of modified IPA range
+ */
+
+#define RSI_HOST_CALL_NR_GPRS		7U
+
+struct rsi_host_call {
+	SET_MEMBER(struct {
+		/* Immediate value */
+		unsigned int imm;		/* Offset 0 */
+		/* Registers */
+		unsigned long gprs[RSI_HOST_CALL_NR_GPRS];
+		}, 0, 0x100);
+};
+
+/*
+ * arg0 == struct rsi_host_call addr
+ */
+#define RSI_HOST_CALL		SMC_RSI_FID(9U)
+
+
+#define RSI_ABI_VERSION		SMC_RSI_FID(0U)
+/*
+ * arg0 == struct rsi_realm_config address
+ */
+#define RSI_REALM_CONFIG	SMC_RSI_FID(6U)
+
+/* This function return RSI_ABI_VERSION */
+u_register_t rsi_get_version(void);
+
+/* This function will call the Host to request IPA of the NS shared buffer */
+u_register_t rsi_get_ns_buffer(void);
+
+/* This function call Host and request to exit Realm with proper exit code */
+void rsi_exit_to_host(enum host_call_cmd exit_code);
+
+#endif /* REALM_RSI_H */
diff --git a/realm/realm_shared_data.c b/realm/realm_shared_data.c
new file mode 100644
index 0000000..da09b53
--- /dev/null
+++ b/realm/realm_shared_data.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <host_shared_data.h>
+
+/**
+ *   @brief    - Returns the base address of the shared region
+ *   @param    - Void
+ *   @return   - Base address of the shared region
+ **/
+
+static host_shared_data_t *guest_shared_data;
+
+/*
+ * Set guest mapped shared buffer pointer
+ */
+void realm_set_shared_structure(host_shared_data_t *ptr)
+{
+	guest_shared_data = ptr;
+}
+
+/*
+ * Get guest mapped shared buffer pointer
+ */
+host_shared_data_t *realm_get_shared_structure(void)
+{
+	return guest_shared_data;
+}
+
+/*
+ * Return Host's data at index
+ */
+u_register_t realm_shared_data_get_host_val(uint8_t index)
+{
+	return guest_shared_data->host_param_val[(index >= MAX_DATA_SIZE) ?
+		(MAX_DATA_SIZE - 1) : index];
+}
+
+/*
+ * Get command sent from Host to realm
+ */
+uint8_t realm_shared_data_get_realm_cmd(void)
+{
+	return guest_shared_data->realm_cmd;
+}
diff --git a/tftf/framework/framework.mk b/tftf/framework/framework.mk
index 11026f2..a2c2a66 100644
--- a/tftf/framework/framework.mk
+++ b/tftf/framework/framework.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -28,6 +28,7 @@
 	-Ispm/cactus					\
 	-Ispm/ivy					\
 	-Ispm/quark					\
+	-Irealm						\
 	-Ismc_fuzz/include
 
 FRAMEWORK_SOURCES	:=	${AUTOGEN_DIR}/tests_list.c
diff --git a/tftf/framework/tftf.ld.S b/tftf/framework/tftf.ld.S
index 9374206..e403af0 100644
--- a/tftf/framework/tftf.ld.S
+++ b/tftf/framework/tftf.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,8 +11,12 @@
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(tftf_entrypoint)
 
+#ifndef TFTF_MAX_IMAGE_SIZE
+#define TFTF_MAX_IMAGE_SIZE DRAM_SIZE
+#endif
+
 MEMORY {
-    RAM (rwx): ORIGIN = DRAM_BASE, LENGTH = DRAM_SIZE
+    RAM (rwx): ORIGIN = TFTF_BASE, LENGTH = TFTF_MAX_IMAGE_SIZE
 }
 
 
diff --git a/tftf/tests/misc_tests/test_invalid_access.c b/tftf/tests/misc_tests/test_invalid_access.c
index 14be340..7e4a861 100644
--- a/tftf/tests/misc_tests/test_invalid_access.c
+++ b/tftf/tests/misc_tests/test_invalid_access.c
@@ -13,17 +13,15 @@
 #ifdef __aarch64__
 #include <sync.h>
 #endif
-#include <test_helpers.h>
+#include <host_realm_helper.h>
 #include <lib/aarch64/arch_features.h>
-#include <runtime_services/realm_payload/realm_payload_test.h>
+#include <test_helpers.h>
 #include <tftf_lib.h>
 #include <xlat_tables_v2.h>
-
 #include <platform_def.h>
 #include <cactus_test_cmds.h>
 #include <ffa_endpoints.h>
 
-
 /*
  * Using "__aarch64__" here looks weird but its unavoidable because of following reason
  * This test is part of standard test which runs on all platforms but pre-requisite
@@ -143,7 +141,7 @@
 	}
 
 	/* Delegate the shared page to Realm. */
-	retmm = realm_granule_delegate((u_register_t)&share_page);
+	retmm = rmi_granule_delegate((u_register_t)&share_page);
 	if (retmm != 0UL) {
 		ERROR("Granule delegate failed!\n");
 		goto out_unregister;
@@ -161,7 +159,7 @@
 
 out_undelegate:
 	/* Undelegate the shared page. */
-	retmm = realm_granule_undelegate((u_register_t)&share_page);
+	retmm = rmi_granule_undelegate((u_register_t)&share_page);
 	if (retmm != 0UL) {
 		ERROR("Granule undelegate failed!\n");
 	}
@@ -233,7 +231,7 @@
 		return TEST_RESULT_SKIPPED;
 	}
 
-	retrmm = realm_version();
+	retrmm = rmi_version();
 
 	VERBOSE("RMM version is: %lu.%lu\n",
 			RMI_ABI_VERSION_GET_MAJOR(retrmm),
@@ -247,17 +245,17 @@
 		return TEST_RESULT_SKIPPED;
 	}
 
-	retrmm = realm_granule_delegate((u_register_t)&rd[0]);
+	retrmm = rmi_granule_delegate((u_register_t)&rd[0]);
 	if (retrmm != 0UL) {
 		ERROR("Delegate operation returns fail, %lx\n", retrmm);
 		return TEST_RESULT_FAIL;
 	}
 
 	/* Create a realm using a parameter in a secure physical address space should fail. */
-	retrmm = realm_create((u_register_t)&rd[0], params);
+	retrmm = rmi_realm_create((u_register_t)&rd[0], params);
 	if (retrmm == 0UL) {
 		ERROR("Realm create operation should fail, %lx\n", retrmm);
-		retrmm = realm_destroy((u_register_t)&rd[0]);
+		retrmm = rmi_realm_destroy((u_register_t)&rd[0]);
 		if (retrmm != 0UL) {
 			ERROR("Realm destroy operation returns fail, %lx\n", retrmm);
 			return TEST_RESULT_FAIL;
@@ -269,7 +267,7 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	retrmm = realm_granule_undelegate((u_register_t)&rd[0]);
+	retrmm = rmi_granule_undelegate((u_register_t)&rd[0]);
 	if (retrmm != 0UL) {
 		INFO("Undelegate operation returns fail, %lx\n", retrmm);
 		return TEST_RESULT_FAIL;
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
new file mode 100644
index 0000000..4b50b5a
--- /dev/null
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <events.h>
+#include <heap/page_alloc.h>
+#include <host_realm_helper.h>
+#include <host_realm_mem_layout.h>
+#include <host_realm_rmi.h>
+#include <host_shared_data.h>
+#include <plat_topology.h>
+#include <power_management.h>
+#include <realm_def.h>
+#include <test_helpers.h>
+#include <xlat_tables_v2.h>
+
+static struct realm realm;
+static bool realm_payload_created;
+static bool shared_mem_created;
+static bool realm_payload_mmaped;
+static u_register_t exit_reason = RMI_EXIT_INVALID;
+static unsigned int test_result = TEST_RESULT_FAIL;
+static volatile bool timer_enabled;
+
+/* From the TFTF_BASE offset, memory used by TFTF + Shared + Realm + POOL should
+ * not exceed DRAM_END offset
+ * NS_REALM_SHARED_MEM_BASE + NS_REALM_SHARED_MEM_SIZE is considered last offset
+ */
+CASSERT((((uint64_t)NS_REALM_SHARED_MEM_BASE + (uint64_t)NS_REALM_SHARED_MEM_SIZE)\
+	< ((uint64_t)DRAM_BASE + (uint64_t)DRAM_SIZE)),\
+	error_ns_memory_and_realm_payload_exceed_DRAM_SIZE);
+
+/*
+ * The function handler to print the Realm logged buffer,
+ * executed by the secondary core
+ */
+static inline test_result_t timer_handler(void)
+{
+	size_t str_len = 0UL;
+	host_shared_data_t *host_shared_data = host_get_shared_structure();
+	char *log_buffer = (char *)host_shared_data->log_buffer;
+
+	do {
+		spin_lock((spinlock_t *)&host_shared_data->printf_lock);
+		str_len = strlen((const char *)log_buffer);
+
+		/*
+		 * Read Realm message from shared printf location and print
+		 * them using uart
+		 */
+		if (str_len != 0UL) {
+			/* Avoid memory overflow */
+			log_buffer[MAX_BUF_SIZE - 1] = 0U;
+
+			mp_printf("%s", log_buffer);
+			(void)memset((char *)log_buffer, 0, MAX_BUF_SIZE);
+		}
+		spin_unlock((spinlock_t *)&host_shared_data->printf_lock);
+
+	} while ((timer_enabled || (str_len != 0UL)));
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * Initialisation function which will clear the shared region,
+ * and try to find another CPU other than the lead one to
+ * handle the Realm message logging
+ */
+void host_init_realm_print_buffer(void)
+{
+	u_register_t other_mpidr, my_mpidr;
+	int ret;
+	host_shared_data_t *host_shared_data = host_get_shared_structure();
+
+	(void)memset((char *)host_shared_data, 0, sizeof(host_shared_data_t));
+	/* Program timer */
+	timer_enabled = false;
+
+	/* Find a valid CPU to power on */
+	my_mpidr = read_mpidr_el1() & MPID_MASK;
+	other_mpidr = tftf_find_any_cpu_other_than(my_mpidr);
+	if (other_mpidr == INVALID_MPID) {
+		ERROR("Couldn't find a valid other CPU\n");
+		return;
+	}
+
+	/* Power on the other CPU */
+	ret = tftf_cpu_on(other_mpidr, (uintptr_t)timer_handler, 0);
+	if (ret != PSCI_E_SUCCESS) {
+		ERROR("powering on %llx failed",
+		(unsigned long long)other_mpidr);
+		return;
+	}
+	timer_enabled = true;
+}
+
+/**
+ *   @brief    - Add regions assigned to Host into its translation table data
+ *   structure.
+ **/
+static test_result_t host_mmap_realm_payload(u_register_t realm_payload_adr,
+		u_register_t plat_mem_pool_adr,
+		u_register_t plat_mem_pool_size)
+{
+	if (realm_payload_mmaped) {
+		return REALM_SUCCESS;
+	}
+
+	/* Memory Pool region */
+	int rc = mmap_add_dynamic_region(plat_mem_pool_adr,
+					plat_mem_pool_adr,
+					plat_mem_pool_size,
+					MT_RW_DATA | MT_NS);
+
+	if (rc != 0) {
+		ERROR("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
+		return TEST_RESULT_FAIL;
+	}
+
+	/* Realm Image region */
+	rc = mmap_add_dynamic_region(realm_payload_adr,
+					realm_payload_adr,
+					REALM_MAX_LOAD_IMG_SIZE,
+					MT_RW_DATA | MT_NS);
+
+	if (rc != 0) {
+		ERROR("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
+		return TEST_RESULT_FAIL;
+	}
+	realm_payload_mmaped = true;
+	return REALM_SUCCESS;
+}
+
+static bool host_enter_realm(u_register_t *exit_reason, unsigned int *test_result)
+{
+	u_register_t ret;
+
+	if (!realm_payload_created) {
+		ERROR("%s failed, Realm not created\n", __func__);
+		return false;
+	}
+	if (!shared_mem_created) {
+		ERROR("%s failed, shared memory not created\n", __func__);
+		return false;
+	}
+
+	/* Enter Realm  */
+	ret = realm_rec_enter(&realm, exit_reason, test_result);
+	if (ret != REALM_SUCCESS) {
+		ERROR("Rec enter failed something went wrong, ret=%lx\n", ret);
+
+		/* Free test resources */
+		if (realm_destroy(&realm) != REALM_SUCCESS) {
+			ERROR("%s\n", "realm_destroy failed");
+		}
+		realm_payload_created = false;
+		return false;
+	}
+
+	return true;
+}
+
+bool host_create_realm_payload(u_register_t realm_payload_adr,
+		u_register_t plat_mem_pool_adr,
+		u_register_t plat_mem_pool_size,
+		u_register_t realm_pages_size)
+{
+	if (realm_payload_adr == TFTF_BASE) {
+		ERROR("realm_payload_adr should grater then TFTF_BASE\n");
+		return false;
+	}
+
+	if (plat_mem_pool_adr  == 0UL ||
+			plat_mem_pool_size == 0UL ||
+			realm_pages_size == 0UL) {
+		ERROR("plat_mem_pool_size or "
+			"plat_mem_pool_size or realm_pages_size isNull\n");
+		return false;
+	}
+	/* Initialize  Host NS heap memory to be used in Realm creation*/
+	if (page_pool_init(plat_mem_pool_adr, realm_pages_size)
+		!= HEAP_INIT_SUCCESS) {
+		ERROR("page_pool_init() failed\n");
+		return false;
+	}
+
+	/* Mmap Realm payload region*/
+	if (host_mmap_realm_payload(realm_payload_adr,
+			plat_mem_pool_adr,
+			plat_mem_pool_size) != REALM_SUCCESS) {
+		ERROR("host_mmap_realm_payload() failed\n");
+		return false;
+	}
+
+	/* Read Realm feature Regs*/
+	if (rmi_features(0UL, &realm.rmm_feat_reg0) != REALM_SUCCESS) {
+		ERROR("rmi_features() Read Realm feature failed\n");
+		goto destroy_realm;
+	}
+
+	/* Create Realm */
+	if (realm_create(&realm) != REALM_SUCCESS) {
+		ERROR("realm_create() failed\n");
+		goto destroy_realm;
+	}
+
+	if (realm_init_ipa_state(&realm, 0U, 0U, 1ULL << 32)
+		!= RMI_SUCCESS) {
+		ERROR("realm_init_ipa_state\n");
+		goto destroy_realm;
+	}
+	/* RTT map Realm image */
+	if (realm_map_payload_image(&realm, realm_payload_adr) !=
+			REALM_SUCCESS) {
+		ERROR("realm_map_payload_image() failed\n");
+		goto destroy_realm;
+	}
+
+	/* Create REC */
+	if (realm_rec_create(&realm) != REALM_SUCCESS) {
+		ERROR("REC create failed\n");
+		goto destroy_realm;
+	}
+
+	/* Activate Realm */
+	if (realm_activate(&realm) != REALM_SUCCESS) {
+		ERROR("Realm activate failed\n");
+		goto destroy_realm;
+	}
+
+	realm_payload_created = true;
+
+	return realm_payload_created;
+
+	/* Free test resources */
+destroy_realm:
+	if (realm_destroy(&realm) != REALM_SUCCESS) {
+		ERROR("%s\n", "realm_destroy failed");
+	}
+	realm_payload_created = false;
+
+	return realm_payload_created;
+}
+
+bool host_create_shared_mem(u_register_t ns_shared_mem_adr,
+	u_register_t ns_shared_mem_size)
+{
+	/* RTT map NS shared region */
+	if (realm_map_ns_shared(&realm, ns_shared_mem_adr, ns_shared_mem_size) !=
+		REALM_SUCCESS) {
+		ERROR("realm_map_ns_shared() failed\n");
+		shared_mem_created = false;
+		return false;
+	}
+
+	host_init_realm_print_buffer();
+	realm_shared_data_clear_realm_val();
+	shared_mem_created = true;
+
+	return shared_mem_created;
+}
+
+bool host_destroy_realm(void)
+{
+	/* Free test resources */
+	timer_enabled = false;
+	page_pool_reset();
+
+	if (!realm_payload_created) {
+		ERROR("realm_destroy failed, Realm not created\n");
+		return false;
+	}
+
+	realm_payload_created = false;
+	if (realm_destroy(&realm) != REALM_SUCCESS) {
+		ERROR("%s\n", "realm_destroy failed");
+		return false;
+	}
+
+	return true;
+}
+
+bool host_enter_realm_execute(uint8_t cmd)
+{
+	exit_reason = RMI_EXIT_INVALID;
+	test_result = TEST_RESULT_FAIL;
+
+	realm_shared_data_set_realm_cmd(cmd);
+	if (!host_enter_realm(&exit_reason, &test_result)) {
+		return false;
+	}
+
+	if (exit_reason == RMI_EXIT_HOST_CALL &&
+		test_result == TEST_RESULT_SUCCESS) {
+		return true;
+	}
+	ERROR("host_enter_realm_execute exit_reason:[0x%lx],test_result:[0x%x]\n",
+		exit_reason,
+		test_result);
+	return false;
+}
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
new file mode 100644
index 0000000..898e22a
--- /dev/null
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
@@ -0,0 +1,1060 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <string.h>
+
+#include <debug.h>
+#include <heap/page_alloc.h>
+#include <host_realm_helper.h>
+#include <host_realm_mem_layout.h>
+#include <host_realm_rmi.h>
+#include <plat/common/platform.h>
+#include <realm_def.h>
+#include <tftf_lib.h>
+
+static inline u_register_t rmi_data_create(bool unknown, u_register_t data,
+		u_register_t rd, u_register_t map_addr, u_register_t src)
+{
+	if (unknown) {
+		return ((smc_ret_values)(tftf_smc(&(smc_args)
+				{RMI_DATA_CREATE_UNKNOWN, data, rd, map_addr,
+			0UL, 0UL, 0UL, 0UL}))).ret0;
+	} else {
+		return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_DATA_CREATE,
+			data, rd, map_addr, src, 0UL, 0UL, 0UL}))).ret0;
+	}
+}
+
+static inline u_register_t rmi_realm_activate(u_register_t rd)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REALM_ACTIVATE,
+		rd, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t rmi_realm_create(u_register_t rd, u_register_t params_ptr)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REALM_CREATE,
+		rd, params_ptr, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t rmi_realm_destroy(u_register_t rd)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REALM_DESTROY,
+		rd, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_data_destroy(u_register_t rd,
+		u_register_t map_addr)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_DATA_DESTROY,
+		rd, map_addr, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rec_create(u_register_t rec, u_register_t rd,
+	u_register_t params_ptr)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REC_CREATE,
+			rec, rd, params_ptr, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rec_destroy(u_register_t rec)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REC_DESTROY,
+		rec, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rtt_create(u_register_t rtt, u_register_t rd,
+	u_register_t map_addr, u_register_t level)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_CREATE,
+			rtt, rd, map_addr, level, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rtt_destroy(u_register_t rtt, u_register_t rd,
+	u_register_t map_addr, u_register_t level)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_DESTROY,
+		rtt, rd, map_addr, level, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t rmi_features(u_register_t index, u_register_t *features)
+{
+	smc_ret_values rets;
+
+	rets = tftf_smc(&(smc_args) {RMI_FEATURES, index, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+	*features = rets.ret1;
+	return rets.ret0;
+}
+
+static inline u_register_t rmi_rtt_init_ripas(u_register_t rd,
+	u_register_t map_addr,
+	u_register_t level)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_INIT_RIPAS,
+		rd, map_addr, level, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rtt_fold(u_register_t rtt, u_register_t rd,
+	u_register_t map_addr, u_register_t level)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_FOLD,
+		rtt, rd, map_addr, level, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rec_aux_count(u_register_t rd,
+	u_register_t *aux_count)
+{
+	smc_ret_values rets;
+
+	rets = tftf_smc(&(smc_args) {RMI_REC_AUX_COUNT, rd, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+	*aux_count = rets.ret1;
+	return rets.ret0;
+}
+
+static inline u_register_t rmi_rtt_set_ripas(u_register_t rd, u_register_t rec,
+	u_register_t map_addr, u_register_t level,
+	u_register_t ripas)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_SET_RIPAS,
+			rd, rec, map_addr, level, ripas, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rtt_mapunprotected(u_register_t rd,
+	u_register_t map_addr,
+	u_register_t level, u_register_t ns_pa)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_MAP_UNPROTECTED,
+		rd, map_addr, level, ns_pa, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static u_register_t rmi_rtt_readentry(u_register_t rd, u_register_t map_addr,
+	u_register_t level, struct rtt_entry *rtt)
+{
+	smc_ret_values rets;
+
+	rets = tftf_smc(&(smc_args) {RMI_RTT_READ_ENTRY,
+		rd, map_addr, level, 0UL, 0UL, 0UL, 0UL});
+
+	rtt->walk_level = rets.ret1;
+	rtt->state = rets.ret2 & 0xFF;
+	rtt->out_addr = rets.ret3;
+	return rets.ret0;
+}
+
+static inline u_register_t rmi_rtt_unmap_unprotected(u_register_t rd,
+	u_register_t map_addr,
+	u_register_t level, u_register_t ns_pa)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_UNMAP_UNPROTECTED,
+		rd, map_addr, level, ns_pa, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rtt_level_mapsize(u_register_t level)
+{
+	if (level > RTT_MAX_LEVEL) {
+		return PAGE_SIZE;
+	}
+
+	return (1UL << RTT_LEVEL_SHIFT(level));
+}
+
+static inline u_register_t realm_rtt_create(struct realm *realm,
+	u_register_t addr,
+	u_register_t level,
+	u_register_t phys)
+{
+	addr = ALIGN_DOWN(addr, rtt_level_mapsize(level - 1U));
+	return rmi_rtt_create(phys, realm->rd, addr, level);
+}
+
+static u_register_t rmi_create_rtt_levels(struct realm *realm,
+	u_register_t map_addr,
+	u_register_t level,
+	u_register_t max_level)
+{
+	u_register_t rtt, ret;
+
+	while (level++ < max_level) {
+		rtt = (u_register_t)page_alloc(PAGE_SIZE);
+		if (rtt == HEAP_NULL_PTR) {
+			ERROR("Failed to allocate memory for rtt\n");
+			return REALM_ERROR;
+		} else {
+			ret = rmi_granule_delegate(rtt);
+			if (ret != RMI_SUCCESS) {
+				ERROR("Rtt delegation failed,"
+					"rtt=0x%lx ret=0x%lx\n", rtt, ret);
+				return REALM_ERROR;
+			}
+		}
+		ret = realm_rtt_create(realm, map_addr, level, rtt);
+		if (ret != RMI_SUCCESS) {
+			ERROR("Rtt create failed,"
+				"rtt=0x%lx ret=0x%lx\n", rtt, ret);
+			rmi_granule_undelegate(rtt);
+			page_free(rtt);
+			return REALM_ERROR;
+		}
+	}
+
+	return REALM_SUCCESS;
+}
+
+static u_register_t realm_fold_rtt(u_register_t rd, u_register_t addr,
+	u_register_t level)
+{
+	struct rtt_entry rtt;
+	u_register_t ret;
+
+	ret = rmi_rtt_readentry(rd, addr, level, &rtt);
+	if (ret != RMI_SUCCESS) {
+		ERROR("Rtt readentry failed,"
+			"level=0x%lx addr=0x%lx ret=0x%lx\n",
+			level, addr, ret);
+		return REALM_ERROR;
+	}
+
+	if (rtt.state != RMI_TABLE) {
+		ERROR("Rtt readentry failed, rtt.state=0x%x\n", rtt.state);
+		return REALM_ERROR;
+	}
+
+	ret = rmi_rtt_fold(rtt.out_addr, rd, addr, level + 1U);
+	if (ret != RMI_SUCCESS) {
+		ERROR("Rtt destroy failed,"
+			"rtt.out_addr=0x%llx addr=0x%lx ret=0x%lx\n",
+			rtt.out_addr, addr, ret);
+		return REALM_ERROR;
+	}
+
+	page_free(rtt.out_addr);
+
+	return REALM_SUCCESS;
+
+}
+
+static u_register_t realm_map_protected_data(bool unknown, struct realm *realm,
+	u_register_t target_pa,
+	u_register_t map_size,
+	u_register_t src_pa)
+{
+	u_register_t rd = realm->rd;
+	u_register_t map_level, level;
+	u_register_t ret = 0UL;
+	u_register_t size;
+	u_register_t phys = target_pa;
+	u_register_t map_addr = target_pa;
+
+	if (!IS_ALIGNED(map_addr, map_size)) {
+		return REALM_ERROR;
+	}
+
+	switch (map_size) {
+	case PAGE_SIZE:
+		map_level = 3UL;
+		break;
+	case RTT_L2_BLOCK_SIZE:
+		map_level = 2UL;
+		break;
+	default:
+		ERROR("Unknown map_size=0x%lx\n", map_size);
+		return REALM_ERROR;
+	}
+
+	ret = rmi_rtt_init_ripas(rd, map_addr, map_level);
+	if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+		ret = rmi_create_rtt_levels(realm, map_addr,
+				RMI_RETURN_INDEX(ret), map_level);
+		if (ret != RMI_SUCCESS) {
+			ERROR("rmi_create_rtt_levels failed,"
+				"ret=0x%lx line:%d\n",
+				ret, __LINE__);
+			goto err;
+		}
+		ret = rmi_rtt_init_ripas(rd, map_addr, map_level);
+		if (ret != RMI_SUCCESS) {
+			ERROR("rmi_create_rtt_levels failed,"
+				"ret=0x%lx line:%d\n",
+				ret, __LINE__);
+			goto err;
+		}
+	}
+	for (size = 0UL; size < map_size; size += PAGE_SIZE) {
+		ret = rmi_granule_delegate(phys);
+		if (ret != RMI_SUCCESS) {
+			ERROR("Granule delegation failed, PA=0x%lx ret=0x%lx\n",
+				phys, ret);
+			return REALM_ERROR;
+		}
+
+		ret = rmi_data_create(unknown, phys, rd, map_addr, src_pa);
+
+		if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+			/* Create missing RTTs and retry */
+			level = RMI_RETURN_INDEX(ret);
+			ret = rmi_create_rtt_levels(realm, map_addr, level,
+				map_level);
+			if (ret != RMI_SUCCESS) {
+				ERROR("rmi_create_rtt_levels failed,"
+					"ret=0x%lx line:%d\n",
+					ret, __LINE__);
+				goto err;
+			}
+
+			ret = rmi_data_create(unknown, phys, rd, map_addr, src_pa);
+		}
+
+		if (ret != RMI_SUCCESS) {
+			ERROR("rmi_data_create failed, ret=0x%lx\n", ret);
+			goto err;
+		}
+
+		phys += PAGE_SIZE;
+		src_pa += PAGE_SIZE;
+		map_addr += PAGE_SIZE;
+	}
+
+	if (map_size == RTT_L2_BLOCK_SIZE) {
+		ret = realm_fold_rtt(rd, target_pa, map_level);
+		if (ret != RMI_SUCCESS) {
+			ERROR("fold_rtt failed, ret=0x%lx\n", ret);
+			goto err;
+		}
+	}
+
+	if (ret != RMI_SUCCESS) {
+		ERROR("rmi_rtt_mapprotected failed, ret=0x%lx\n", ret);
+		goto err;
+	}
+
+	return REALM_SUCCESS;
+
+err:
+	while (size >= PAGE_SIZE) {
+		ret = rmi_data_destroy(rd, map_addr);
+		if (ret != RMI_SUCCESS) {
+			ERROR("rmi_rtt_mapprotected failed, ret=0x%lx\n", ret);
+		}
+
+		ret = rmi_granule_undelegate(phys);
+		if (ret != RMI_SUCCESS) {
+			/* Page can't be returned to NS world so is lost */
+			ERROR("rmi_granule_undelegate failed\n");
+		}
+		phys -= PAGE_SIZE;
+		size -= PAGE_SIZE;
+		map_addr -= PAGE_SIZE;
+	}
+
+	return REALM_ERROR;
+}
+
+u_register_t realm_map_unprotected(struct realm *realm,
+	u_register_t ns_pa,
+	u_register_t map_size)
+{
+	u_register_t rd = realm->rd;
+	u_register_t map_level, level;
+	u_register_t ret = 0UL;
+	u_register_t phys = ns_pa;
+	u_register_t map_addr = ns_pa |
+			(1UL << (EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ,
+			realm->rmm_feat_reg0) - 1UL)) ;
+
+
+	if (!IS_ALIGNED(map_addr, map_size)) {
+		return REALM_ERROR;
+	}
+
+	switch (map_size) {
+	case PAGE_SIZE:
+		map_level = 3UL;
+		break;
+	case RTT_L2_BLOCK_SIZE:
+		map_level = 2UL;
+		break;
+	default:
+		ERROR("Unknown map_size=0x%lx\n", map_size);
+		return REALM_ERROR;
+	}
+
+	u_register_t desc = phys | S2TTE_ATTR_FWB_WB_RW;
+
+	ret = rmi_rtt_mapunprotected(rd, map_addr, map_level, desc);
+
+	if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+		/* Create missing RTTs and retry */
+		level = RMI_RETURN_INDEX(ret);
+		ret = rmi_create_rtt_levels(realm, map_addr, level, map_level);
+		if (ret != RMI_SUCCESS) {
+			ERROR("rmi_create_rtt_levels failed, ret=0x%lx line:%d\n",
+					ret, __LINE__);
+			return REALM_ERROR;
+		}
+
+		ret = rmi_rtt_mapunprotected(rd, map_addr, map_level, desc);
+	}
+	if (ret != RMI_SUCCESS) {
+		ERROR("al_rmi_rtt_mapunprotected failed, ret=0x%lx\n", ret);
+		return REALM_ERROR;
+	}
+
+	return REALM_SUCCESS;
+}
+
+static u_register_t realm_rtt_destroy(struct realm *realm, u_register_t addr,
+	u_register_t level,
+	u_register_t rtt_granule)
+{
+	addr = ALIGN_DOWN(addr, rtt_level_mapsize(level - 1U));
+	return rmi_rtt_destroy(rtt_granule, realm->rd, addr, level);
+}
+
+static u_register_t realm_destroy_free_rtt(struct realm *realm,
+	u_register_t addr,
+	u_register_t level, u_register_t rtt_granule)
+{
+	u_register_t ret;
+
+	ret = realm_rtt_destroy(realm, addr, level, rtt_granule);
+	if (ret != RMI_SUCCESS) {
+		ERROR("realm_rtt_destroy failed, rtt=0x%lx, ret=0x%lx\n",
+				rtt_granule, ret);
+		return REALM_ERROR;
+	}
+
+	ret = rmi_granule_undelegate(rtt_granule);
+	if (ret != RMI_SUCCESS) {
+		ERROR("rmi_granule_undelegate failed, rtt=0x%lx, ret=0x%lx\n",
+				rtt_granule, ret);
+		return REALM_ERROR;
+	}
+
+	page_free(rtt_granule);
+	return REALM_SUCCESS;
+}
+
+static void realm_destroy_undelegate_range(struct realm *realm,
+	u_register_t ipa,
+	u_register_t addr,
+	u_register_t size)
+{
+	u_register_t rd = realm->rd;
+	u_register_t ret;
+
+	while (size >= PAGE_SIZE) {
+		ret = rmi_data_destroy(rd, ipa);
+		if (ret != RMI_SUCCESS) {
+			ERROR("rmi_data_destroy failed, addr=0x%lx, ret=0x%lx\n",
+				ipa, ret);
+		}
+
+		ret = rmi_granule_undelegate(addr);
+		if (ret != RMI_SUCCESS) {
+			ERROR("al_rmi_granule_undelegate failed, addr=0x%lx,"
+			"ret=0x%lx\n",
+			ipa, ret);
+		}
+
+		page_free(addr);
+
+		addr += PAGE_SIZE;
+		ipa += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+}
+
+static u_register_t realm_tear_down_rtt_range(struct realm *realm,
+	u_register_t level,
+	u_register_t start,
+	u_register_t end)
+{
+	u_register_t rd = realm->rd, ret;
+	u_register_t map_size = rtt_level_mapsize(level);
+	u_register_t map_addr, next_addr, rtt_out_addr, end_addr;
+	struct rtt_entry rtt;
+
+	for (map_addr = start; map_addr < end; map_addr = next_addr) {
+		next_addr = ALIGN(map_addr + 1U, map_size);
+		end_addr = MIN(next_addr, end);
+
+		ret = rmi_rtt_readentry(rd, ALIGN_DOWN(map_addr, map_size),
+			level, &rtt);
+		if (ret != RMI_SUCCESS) {
+			continue;
+		}
+
+		rtt_out_addr = rtt.out_addr;
+
+		switch (rtt.state) {
+		case RMI_ASSIGNED:
+			realm_destroy_undelegate_range(realm, map_addr,
+					rtt_out_addr, map_size);
+			break;
+		case RMI_UNASSIGNED:
+		case RMI_DESTROYED:
+			break;
+		case RMI_TABLE:
+			ret = realm_tear_down_rtt_range(realm, level + 1U,
+				map_addr, end_addr);
+			if (ret != RMI_SUCCESS) {
+				ERROR("realm_tear_down_rtt_range failed, \
+					map_addr=0x%lx ret=0x%lx\n",
+					map_addr, ret);
+				return REALM_ERROR;
+			}
+
+			ret = realm_destroy_free_rtt(realm, map_addr, level + 1U,
+					rtt_out_addr);
+			if (ret != RMI_SUCCESS) {
+				ERROR("rrt destroy can't be performed failed, \
+					map_addr=0x%lx ret=0x%lx\n",
+					map_addr, ret);
+				return REALM_ERROR;
+			}
+			break;
+		case RMI_VALID_NS:
+			ret = rmi_rtt_unmap_unprotected(rd, map_addr, level,
+				rtt_out_addr);
+			if (ret != RMI_SUCCESS) {
+				ERROR("rmi_rtt_unmap_unprotected failed,"
+				"addr=0x%lx, ret=0x%lx\n",
+					  map_addr, ret);
+				return REALM_ERROR;
+			}
+			break;
+		default:
+			return REALM_ERROR;
+		}
+	}
+
+	return REALM_SUCCESS;
+}
+
+u_register_t rmi_granule_delegate(u_register_t addr)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_GRANULE_DELEGATE,
+			addr, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t rmi_granule_undelegate(u_register_t addr)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_GRANULE_UNDELEGATE,
+			addr, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t rmi_version(void)
+{
+	return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_VERSION,
+			0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t realm_create(struct realm *realm)
+{
+	struct rmi_realm_params *params;
+	u_register_t ret;
+
+	realm->par_size = REALM_MAX_LOAD_IMG_SIZE;
+
+	realm->state = REALM_STATE_NULL;
+	/*
+	 * Allocate memory for PAR - Realm image. Granule delegation
+	 * of PAR will be performed during rtt creation.
+	 */
+	realm->par_base = (u_register_t)page_alloc(realm->par_size);
+	if (realm->par_base == HEAP_NULL_PTR) {
+		ERROR("page_alloc failed, base=0x%lx, size=0x%lx\n",
+			  realm->par_base, realm->par_size);
+		return REALM_ERROR;
+	}
+
+	/* Allocate and delegate RD */
+	realm->rd = (u_register_t)page_alloc(PAGE_SIZE);
+	if (realm->rd == HEAP_NULL_PTR) {
+		ERROR("Failed to allocate memory for rd\n");
+		goto err_free_par;
+	} else {
+		ret = rmi_granule_delegate(realm->rd);
+		if (ret != RMI_SUCCESS) {
+			ERROR("rd delegation failed, rd=0x%lx, ret=0x%lx\n",
+					realm->rd, ret);
+			goto err_free_rd;
+		}
+	}
+
+	/* Allocate and delegate RTT */
+	realm->rtt_addr = (u_register_t)page_alloc(PAGE_SIZE);
+	if (realm->rtt_addr == HEAP_NULL_PTR) {
+		ERROR("Failed to allocate memory for rtt_addr\n");
+		goto err_undelegate_rd;
+	} else {
+		ret = rmi_granule_delegate(realm->rtt_addr);
+		if (ret != RMI_SUCCESS) {
+			ERROR("rtt delegation failed, rtt_addr=0x%lx, ret=0x%lx\n",
+					realm->rtt_addr, ret);
+			goto err_free_rtt;
+		}
+	}
+
+	/* Allocate memory for params */
+	params = (struct rmi_realm_params *)page_alloc(PAGE_SIZE);
+	if (params == NULL) {
+		ERROR("Failed to allocate memory for params\n");
+		goto err_undelegate_rtt;
+	}
+
+	/* Populate params */
+	params->features_0 = realm->rmm_feat_reg0;
+	params->rtt_level_start = 0L;
+	params->rtt_num_start = 1U;
+	params->rtt_base = realm->rtt_addr;
+	params->vmid = 1U;
+	params->hash_algo = RMI_HASH_SHA_256;
+
+	/* Create Realm */
+	ret = rmi_realm_create(realm->rd, (u_register_t)params);
+	if (ret != RMI_SUCCESS) {
+		ERROR("Realm create failed, rd=0x%lx, ret=0x%lx\n", realm->rd,
+		ret);
+		goto err_free_params;
+	}
+
+	ret = rmi_rec_aux_count(realm->rd, &realm->num_aux);
+	if (ret != RMI_SUCCESS) {
+		ERROR("rmi_rec_aux_count failed, rd=0x%lx, ret=0x%lx\n", realm->rd,
+		ret);
+		rmi_realm_destroy(realm->rd);
+		goto err_free_params;
+	}
+
+	realm->state = REALM_STATE_NEW;
+
+	/* Free params */
+	page_free((u_register_t)params);
+	return REALM_SUCCESS;
+
+err_free_params:
+	page_free((u_register_t)params);
+
+err_undelegate_rtt:
+	ret = rmi_granule_undelegate(realm->rtt_addr);
+	if (ret != RMI_SUCCESS) {
+		WARN("rtt undelegation failed, rtt_addr=0x%lx, ret=0x%lx\n",
+		realm->rtt_addr, ret);
+	}
+
+err_free_rtt:
+	page_free(realm->rtt_addr);
+
+err_undelegate_rd:
+	ret = rmi_granule_undelegate(realm->rd);
+	if (ret != RMI_SUCCESS) {
+		WARN("rd undelegation failed, rd=0x%lx, ret=0x%lx\n", realm->rd,
+		ret);
+	}
+err_free_rd:
+	page_free(realm->rd);
+
+err_free_par:
+	page_free(realm->par_base);
+
+	return REALM_ERROR;
+}
+
+u_register_t realm_map_payload_image(struct realm *realm,
+	u_register_t realm_payload_adr)
+{
+	u_register_t src_pa = realm_payload_adr;
+	u_register_t i = 0UL;
+	u_register_t ret;
+
+	/* MAP image regions */
+	while (i < (realm->par_size / PAGE_SIZE)) {
+		ret =	realm_map_protected_data(false, realm,
+				realm->par_base + i * PAGE_SIZE,
+				PAGE_SIZE,
+				src_pa + i * PAGE_SIZE);
+		if (ret != RMI_SUCCESS) {
+			ERROR("realm_map_protected_data failed,"
+				"par_base=0x%lx ret=0x%lx\n",
+				realm->par_base, ret);
+			return REALM_ERROR;
+		}
+		i++;
+	}
+
+	return REALM_SUCCESS;
+}
+
+u_register_t realm_init_ipa_state(struct realm *realm,
+		u_register_t level,
+		u_register_t start,
+		uint64_t end)
+{
+	u_register_t rd = realm->rd, ret;
+	u_register_t map_size = rtt_level_mapsize(level);
+
+	while (start < end) {
+		ret = rmi_rtt_init_ripas(rd, start, level);
+
+		if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+			int cur_level = RMI_RETURN_INDEX(ret);
+
+			if (cur_level < level) {
+				ret = rmi_create_rtt_levels(realm,
+						start,
+						cur_level,
+						level);
+				if (ret != RMI_SUCCESS) {
+					ERROR("rmi_create_rtt_levels failed,"
+						"ret=0x%lx line:%d\n",
+						ret, __LINE__);
+					return ret;
+				}
+				/* Retry with the RTT levels in place */
+				continue;
+			}
+
+			if (level >= RTT_MAX_LEVEL) {
+				return REALM_ERROR;
+			}
+
+			/* There's an entry at a lower level, recurse */
+			realm_init_ipa_state(realm, start, start + map_size,
+					     level + 1);
+		} else if (ret != RMI_SUCCESS) {
+			return REALM_ERROR;
+		}
+
+		start += map_size;
+	}
+
+	return RMI_SUCCESS;
+}
+
+u_register_t realm_map_ns_shared(struct realm *realm,
+	u_register_t ns_shared_mem_adr,
+	u_register_t ns_shared_mem_size)
+{
+	u_register_t i = 0UL;
+	u_register_t ret;
+
+	realm->ipa_ns_buffer = ns_shared_mem_adr |
+			(1UL << (EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ,
+			realm->rmm_feat_reg0) - 1));
+	realm->ns_buffer_size = ns_shared_mem_size;
+	/* MAP SHARED_NS region */
+	while (i < ns_shared_mem_size / PAGE_SIZE) {
+		ret = realm_map_unprotected(realm,
+			ns_shared_mem_adr + i * PAGE_SIZE, PAGE_SIZE);
+		if (ret != RMI_SUCCESS) {
+			ERROR("\trealm_map_unprotected failepar"
+			"base=0x%lx ret=0x%lx\n",
+			(ns_shared_mem_adr + i * PAGE_SIZE), ret);
+			return REALM_ERROR;
+		}
+		i++;
+	}
+	return REALM_SUCCESS;
+}
+
+static void realm_free_rec_aux(u_register_t *aux_pages, unsigned int num_aux)
+{
+	u_register_t ret;
+
+	for (unsigned int i = 0U; i < num_aux; i++) {
+		ret = rmi_granule_undelegate(aux_pages[i]);
+		if (ret != RMI_SUCCESS) {
+			WARN("realm_free_rec_aux undelegation failed,"
+				"index=%u, ret=0x%lx\n",
+				i, ret);
+		}
+		page_free(aux_pages[i]);
+	}
+}
+
+static u_register_t realm_alloc_rec_aux(struct realm *realm,
+		struct rmi_rec_params *params)
+{
+	u_register_t ret;
+	unsigned int i;
+
+	for (i = 0; i < realm->num_aux; i++) {
+		params->aux[i] = (u_register_t)page_alloc(PAGE_SIZE);
+		if (params->aux[i] == HEAP_NULL_PTR) {
+			ERROR("Failed to allocate memory for aux rec\n");
+			goto err_free_mem;
+		}
+		ret = rmi_granule_delegate(params->aux[i]);
+		if (ret != RMI_SUCCESS) {
+			ERROR("aux rec delegation failed at index=%d, ret=0x%lx\n",
+					i, ret);
+			goto err_free_mem;
+		}
+
+		/* We need a copy in Realm object for final destruction */
+		realm->aux_pages[i] = params->aux[i];
+	}
+	return RMI_SUCCESS;
+err_free_mem:
+	realm_free_rec_aux(params->aux, i);
+	return ret;
+}
+
+u_register_t realm_rec_create(struct realm *realm)
+{
+	struct rmi_rec_params *rec_params = HEAP_NULL_PTR;
+	u_register_t ret;
+
+	/* Allocate memory for run object */
+	realm->run = (u_register_t)page_alloc(PAGE_SIZE);
+	if (realm->run == HEAP_NULL_PTR) {
+		ERROR("Failed to allocate memory for run\n");
+		return REALM_ERROR;
+	}
+	(void)memset((void *)realm->run, 0x0, PAGE_SIZE);
+
+	/* Allocate and delegate REC */
+	realm->rec = (u_register_t)page_alloc(PAGE_SIZE);
+	if (realm->rec == HEAP_NULL_PTR) {
+		ERROR("Failed to allocate memory for REC\n");
+		goto err_free_mem;
+	} else {
+		ret = rmi_granule_delegate(realm->rec);
+		if (ret != RMI_SUCCESS) {
+			ERROR("rec delegation failed, rec=0x%lx, ret=0x%lx\n",
+					realm->rd, ret);
+			goto err_free_mem;
+		}
+	}
+
+	/* Allocate memory for rec_params */
+	rec_params = (struct rmi_rec_params *)page_alloc(PAGE_SIZE);
+	if (rec_params == NULL) {
+		ERROR("Failed to allocate memory for rec_params\n");
+		goto err_undelegate_rec;
+	}
+	(void)memset(rec_params, 0x0, PAGE_SIZE);
+
+	/* Populate rec_params */
+	for (unsigned int i = 0UL; i < (sizeof(rec_params->gprs) /
+			sizeof(rec_params->gprs[0]));
+			i++) {
+		rec_params->gprs[i] = 0x0UL;
+	}
+
+	/* Delegate the required number of auxiliary Granules  */
+	ret = realm_alloc_rec_aux(realm, rec_params);
+	if (ret != RMI_SUCCESS) {
+		ERROR("REC realm_alloc_rec_aux, ret=0x%lx\n", ret);
+		goto err_free_mem;
+	}
+
+	rec_params->pc = realm->par_base;
+	rec_params->flags = RMI_RUNNABLE;
+	rec_params->mpidr = 0x0UL;
+	rec_params->num_aux = realm->num_aux;
+
+	/* Create REC  */
+	ret = rmi_rec_create(realm->rec, realm->rd,
+			(u_register_t)rec_params);
+	if (ret != RMI_SUCCESS) {
+		ERROR("REC create failed, ret=0x%lx\n", ret);
+		goto err_free_rec_aux;
+	}
+
+	/* Free rec_params */
+	page_free((u_register_t)rec_params);
+	return REALM_SUCCESS;
+
+err_free_rec_aux:
+	realm_free_rec_aux(rec_params->aux, realm->num_aux);
+
+err_undelegate_rec:
+	ret = rmi_granule_undelegate(realm->rec);
+	if (ret != RMI_SUCCESS) {
+		WARN("rec undelegation failed, rec=0x%lx, ret=0x%lx\n",
+				realm->rec, ret);
+	}
+
+err_free_mem:
+	page_free(realm->run);
+	page_free(realm->rec);
+	page_free((u_register_t)rec_params);
+
+	return REALM_ERROR;
+}
+
+u_register_t realm_activate(struct realm *realm)
+{
+	u_register_t ret;
+
+	/* Activate Realm  */
+	ret = rmi_realm_activate(realm->rd);
+	if (ret != RMI_SUCCESS) {
+		ERROR("Realm activate failed, ret=0x%lx\n", ret);
+		return REALM_ERROR;
+	}
+
+	realm->state = REALM_STATE_ACTIVE;
+
+	return REALM_SUCCESS;
+}
+
+u_register_t realm_destroy(struct realm *realm)
+{
+	u_register_t ret;
+
+	if (realm->state == REALM_STATE_NULL) {
+		return REALM_SUCCESS;
+	}
+
+	if (realm->state == REALM_STATE_NEW) {
+		goto undo_from_new_state;
+	}
+
+	if (realm->state != REALM_STATE_ACTIVE) {
+		ERROR("Invalid realm state found =0x%x\n", realm->state);
+		return REALM_ERROR;
+	}
+
+	/* For each REC - Destroy, undelegate and free */
+	ret = rmi_rec_destroy(realm->rec);
+	if (ret != RMI_SUCCESS) {
+		ERROR("REC destroy failed, rec=0x%lx, ret=0x%lx\n",
+				realm->rec, ret);
+		return REALM_ERROR;
+	}
+
+	ret = rmi_granule_undelegate(realm->rec);
+	if (ret != RMI_SUCCESS) {
+		ERROR("rec undelegation failed, rec=0x%lx, ret=0x%lx\n",
+				realm->rec, ret);
+		return REALM_ERROR;
+	}
+
+	realm_free_rec_aux(realm->aux_pages, realm->num_aux);
+	page_free(realm->rec);
+
+	/* Free run object */
+	page_free(realm->run);
+
+	/*
+	 * For each data granule - Destroy, undelegate and free
+	 * RTTs (level 1U and below) must be destroyed leaf-upwards,
+	 * using RMI_DATA_DESTROY, RMI_RTT_DESTROY and RMI_GRANULE_UNDELEGATE
+	 * commands.
+	 */
+	if (realm_tear_down_rtt_range(realm, 0UL, 0UL,
+			(1UL << (EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ,
+			realm->rmm_feat_reg0) - 1))) != RMI_SUCCESS) {
+		ERROR("realm_tear_down_rtt_range\n");
+		return REALM_ERROR;
+	}
+	if (realm_tear_down_rtt_range(realm, 0UL, realm->ipa_ns_buffer,
+			(realm->ipa_ns_buffer + realm->ns_buffer_size)) !=
+			RMI_SUCCESS) {
+		ERROR("realm_tear_down_rtt_range\n");
+		return REALM_ERROR;
+	}
+undo_from_new_state:
+
+	/*
+	 * RD Destroy, undelegate and free
+	 * RTT(L0) undelegate and free
+	 * PAR free
+	 */
+	ret = rmi_realm_destroy(realm->rd);
+	if (ret != RMI_SUCCESS) {
+		ERROR("Realm destroy failed, rd=0x%lx, ret=0x%lx\n",
+				realm->rd, ret);
+		return REALM_ERROR;
+	}
+
+	ret = rmi_granule_undelegate(realm->rd);
+	if (ret != RMI_SUCCESS) {
+		ERROR("rd undelegation failed, rd=0x%lx, ret=0x%lx\n",
+				realm->rd, ret);
+		return REALM_ERROR;
+	}
+
+	ret = rmi_granule_undelegate(realm->rtt_addr);
+	if (ret != RMI_SUCCESS) {
+		ERROR("rtt undelegation failed, rtt_addr=0x%lx, ret=0x%lx\n",
+				realm->rtt_addr, ret);
+		return REALM_ERROR;
+	}
+
+	page_free(realm->rd);
+	page_free(realm->rtt_addr);
+	page_free(realm->par_base);
+
+	return REALM_SUCCESS;
+}
+
+
+u_register_t realm_rec_enter(struct realm *realm, u_register_t *exit_reason,
+		unsigned int *test_result)
+{
+	struct rmi_rec_run *run = (struct rmi_rec_run *)realm->run;
+	u_register_t ret;
+	bool re_enter_rec;
+
+	do {
+		re_enter_rec = false;
+		ret = ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REC_ENTER,
+				realm->rec, realm->run,
+				0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+		VERBOSE("rmi_rec_enter, \
+				run->exit_reason=0x%lx, \
+				run->exit.esr=0x%llx, \
+				EC_BITS=%d, \
+				ISS_DFSC_MASK=0x%llx\n",
+				run->exit_reason,
+				run->exit.esr,
+				((EC_BITS(run->exit.esr) == EC_DABORT_CUR_EL)),
+				(ISS_BITS(run->exit.esr) & ISS_DFSC_MASK));
+
+		/* If a data abort because of a GPF. */
+
+		if (EC_BITS(run->exit.esr) == EC_DABORT_CUR_EL) {
+			ERROR("EC_BITS(run->exit.esr) == EC_DABORT_CUR_EL\n");
+			if ((ISS_BITS(run->exit.esr) & ISS_DFSC_MASK) ==
+				DFSC_GPF_DABORT) {
+				ERROR("DFSC_GPF_DABORT\n");
+			}
+		}
+
+
+		if (ret != RMI_SUCCESS) {
+			return ret;
+		}
+
+		if (run->exit.exit_reason == RMI_EXIT_HOST_CALL) {
+			switch (run->exit.imm) {
+			case HOST_CALL_GET_SHARED_BUFF_CMD:
+				run->entry.gprs[0] = realm->ipa_ns_buffer;
+				re_enter_rec = true;
+				break;
+			case HOST_CALL_EXIT_SUCCESS_CMD:
+				*test_result =  TEST_RESULT_SUCCESS;
+				break;
+			case HOST_CALL_EXIT_FAILED_CMD:
+				*test_result =  TEST_RESULT_FAIL;
+				break;
+			default:
+				break;
+			}
+
+		}
+
+	} while (re_enter_rec);
+
+	*exit_reason = run->exit.exit_reason;
+
+	return ret;
+}
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_shared_data.c b/tftf/tests/runtime_services/host_realm_managment/host_shared_data.c
new file mode 100644
index 0000000..bd571c7
--- /dev/null
+++ b/tftf/tests/runtime_services/host_realm_managment/host_shared_data.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <host_realm_mem_layout.h>
+#include <host_shared_data.h>
+
+static host_shared_data_t *host_shared_data =
+		((host_shared_data_t *)(NS_REALM_SHARED_MEM_BASE));
+static host_shared_data_t *guest_shared_data;
+/*
+ * Return shared buffer pointer mapped as host_shared_data_t structure
+ */
+host_shared_data_t *host_get_shared_structure(void)
+{
+	return host_shared_data;
+}
+
+/*
+ * Set guest mapped shared buffer pointer
+ */
+void realm_set_shared_structure(host_shared_data_t *ptr)
+{
+	guest_shared_data = ptr;
+}
+
+/*
+ * Get guest mapped shared buffer pointer
+ */
+host_shared_data_t *realm_get_shared_structure(void)
+{
+	return guest_shared_data;
+}
+
+/*
+ * Set data to be shared from Host to realm
+ */
+void realm_shared_data_set_host_val(uint8_t index, u_register_t val)
+{
+	host_shared_data->host_param_val[(index >= MAX_DATA_SIZE) ?
+		(MAX_DATA_SIZE - 1) : index] = val;
+}
+
+/*
+ * Set data to be shared from realm to Host
+ */
+void realm_shared_data_set_realm_val(uint8_t index, u_register_t val)
+{
+	host_shared_data->realm_out_val[(index >= MAX_DATA_SIZE) ?
+		(MAX_DATA_SIZE - 1) : index] = val;
+}
+
+/*
+ * Return Host's data at index
+ */
+u_register_t realm_shared_data_get_host_val(uint8_t index)
+{
+	return guest_shared_data->host_param_val[(index >= MAX_DATA_SIZE) ?
+		(MAX_DATA_SIZE - 1) : index];
+}
+
+/*
+ * Return Realm's data at index
+ */
+u_register_t realm_shared_data_get_realm_val(uint8_t index)
+{
+	return host_shared_data->realm_out_val[(index >= MAX_DATA_SIZE) ?
+		(MAX_DATA_SIZE - 1) : index];
+}
+
+/*
+ * Clear shared realm data
+ */
+void realm_shared_data_clear_realm_val(void)
+{
+	(void)memset((char *)host_shared_data->realm_out_val, 0,
+	MAX_DATA_SIZE * sizeof(host_shared_data->realm_out_val[0]));
+}
+
+/*
+ * Clear shared Host data
+ */
+void realm_shared_data_clear_host_val(void)
+{
+	(void)memset((char *)host_shared_data->host_param_val, 0,
+	MAX_DATA_SIZE * sizeof(host_shared_data->host_param_val[0]));
+}
+
+/*
+ * Get command sent from Host to realm
+ */
+uint8_t realm_shared_data_get_realm_cmd(void)
+{
+	return guest_shared_data->realm_cmd;
+}
+
+/*
+ * Set command to be send from Host to realm
+ */
+void realm_shared_data_set_realm_cmd(uint8_t cmd)
+{
+	host_shared_data->realm_cmd = cmd;
+}
diff --git a/tftf/tests/runtime_services/realm_payload/realm_payload_test.c b/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
similarity index 85%
rename from tftf/tests/runtime_services/realm_payload/realm_payload_test.c
rename to tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
index 8bdc60a..17ff651 100644
--- a/tftf/tests/runtime_services/realm_payload/realm_payload_test.c
+++ b/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.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
  */
@@ -7,17 +7,23 @@
 #include <stdlib.h>
 
 #include <arch_features.h>
+#include <host_realm_helper.h>
+#include <host_realm_mem_layout.h>
+#include <host_shared_data.h>
 #include <plat_topology.h>
-#include <power_management.h>
 #include <platform.h>
-#include <runtime_services/realm_payload/realm_payload_test.h>
+#include <power_management.h>
+#include "rmi_spm_tests.h"
 #include <test_helpers.h>
 
+
+
 static test_result_t realm_multi_cpu_payload_test(void);
 static test_result_t realm_multi_cpu_payload_del_undel(void);
 
 /* Buffer to delegate and undelegate */
-static char bufferdelegate[NUM_GRANULES * GRANULE_SIZE * PLATFORM_CORE_COUNT] __aligned(GRANULE_SIZE);
+static char bufferdelegate[NUM_GRANULES * GRANULE_SIZE * PLATFORM_CORE_COUNT]
+	__aligned(GRANULE_SIZE);
 static char bufferstate[NUM_GRANULES * PLATFORM_CORE_COUNT];
 
 /*
@@ -41,12 +47,14 @@
 {
 	u_register_t retrmm;
 
-	for (int i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
+	for (uint32_t i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
 		if ((rand() % 2) == 0) {
-			retrmm = realm_granule_delegate((u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
+			retrmm = rmi_granule_delegate(
+					(u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
 			bufferstate[i] = B_DELEGATED;
 			if (retrmm != 0UL) {
-				tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
+				tftf_testcase_printf("Delegate operation returns fail, %lx\n",
+						retrmm);
 				return TEST_RESULT_FAIL;
 			}
 		} else {
@@ -67,7 +75,7 @@
 		return TEST_RESULT_SKIPPED;
 	}
 
-	retrmm = realm_version();
+	retrmm = rmi_version();
 
 	tftf_testcase_printf("RMM version is: %lu.%lu\n",
 			RMI_ABI_VERSION_GET_MAJOR(retrmm),
@@ -138,12 +146,12 @@
 		return TEST_RESULT_SKIPPED;
 	}
 
-	retrmm = realm_granule_delegate((u_register_t)bufferdelegate);
+	retrmm = rmi_granule_delegate((u_register_t)bufferdelegate);
 	if (retrmm != 0UL) {
 		tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
 		return TEST_RESULT_FAIL;
 	}
-	retrmm = realm_granule_undelegate((u_register_t)bufferdelegate);
+	retrmm = rmi_granule_undelegate((u_register_t)bufferdelegate);
 	if (retrmm != 0UL) {
 		tftf_testcase_printf("Undelegate operation returns fail, %lx\n", retrmm);
 		return TEST_RESULT_FAIL;
@@ -156,7 +164,7 @@
 
 static test_result_t realm_multi_cpu_payload_test(void)
 {
-	u_register_t retrmm = realm_version();
+	u_register_t retrmm = rmi_version();
 
 	tftf_testcase_printf("Multi CPU RMM version on CPU %llx is: %lu.%lu\n",
 			(long long)read_mpidr_el1() & MPID_MASK, RMI_ABI_VERSION_GET_MAJOR(retrmm),
@@ -221,12 +229,14 @@
 	 * Cleanup to set all granules back to undelegated
 	 */
 
-	for (int i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
+	for (uint32_t i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
 		if (bufferstate[i] == B_DELEGATED) {
-			retrmm = realm_granule_undelegate((u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
+			retrmm = rmi_granule_undelegate(
+					(u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
 			bufferstate[i] = B_UNDELEGATED;
 			if (retrmm != 0UL) {
-				tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
+				tftf_testcase_printf("Delegate operation returns fail, %lx\n",
+						retrmm);
 				return TEST_RESULT_FAIL;
 			}
 		}
@@ -250,13 +260,13 @@
 
 	cpu_node = platform_get_core_pos(read_mpidr_el1() & MPID_MASK);
 
-	for (int i = 0; i < NUM_GRANULES; i++) {
+	for (uint32_t i = 0; i < NUM_GRANULES; i++) {
 		if (bufferstate[((cpu_node * NUM_GRANULES) + i)] == B_UNDELEGATED) {
-			retrmm = realm_granule_delegate((u_register_t)
+			retrmm = rmi_granule_delegate((u_register_t)
 					&bufferdelegate[((cpu_node * NUM_GRANULES) + i) * GRANULE_SIZE]);
 			bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_DELEGATED;
 		} else {
-			retrmm = realm_granule_undelegate((u_register_t)
+			retrmm = rmi_granule_undelegate((u_register_t)
 					&bufferdelegate[((cpu_node * NUM_GRANULES) + i) * GRANULE_SIZE]);
 			bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_UNDELEGATED;
 		}
@@ -281,7 +291,7 @@
 
 	u_register_t retrmm;
 
-	retrmm = realm_granule_delegate((u_register_t)&bufferdelegate[0]);
+	retrmm = rmi_granule_delegate((u_register_t)&bufferdelegate[0]);
 
 	if (retrmm != 0UL) {
 		tftf_testcase_printf
@@ -289,7 +299,7 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	retrmm = realm_granule_delegate((u_register_t)&bufferdelegate[0]);
+	retrmm = rmi_granule_delegate((u_register_t)&bufferdelegate[0]);
 
 	if (retrmm == 0UL) {
 		tftf_testcase_printf
@@ -297,7 +307,7 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	retrmm = realm_granule_undelegate((u_register_t)&bufferdelegate[1]);
+	retrmm = rmi_granule_undelegate((u_register_t)&bufferdelegate[1]);
 
 	if (retrmm == 0UL) {
 		tftf_testcase_printf
@@ -305,7 +315,7 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	retrmm = realm_granule_undelegate((u_register_t)&bufferdelegate[0]);
+	retrmm = rmi_granule_undelegate((u_register_t)&bufferdelegate[0]);
 
 	if (retrmm != 0UL) {
 		tftf_testcase_printf
diff --git a/tftf/tests/runtime_services/realm_payload/realm_payload_spm_test.c b/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
similarity index 93%
rename from tftf/tests/runtime_services/realm_payload/realm_payload_spm_test.c
rename to tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
index 1aaa12c..2a0e1e1 100644
--- a/tftf/tests/runtime_services/realm_payload/realm_payload_spm_test.c
+++ b/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
@@ -6,20 +6,19 @@
 
 #include <stdlib.h>
 
-#include <debug.h>
-#include <smccc.h>
-
 #include <arch_helpers.h>
 #include <cactus_test_cmds.h>
+#include <debug.h>
 #include <ffa_endpoints.h>
 #include <ffa_svc.h>
+#include <host_realm_helper.h>
 #include <lib/events.h>
 #include <lib/power_management.h>
-#include <platform.h>
-#include <test_helpers.h>
-
 #include <plat_topology.h>
-#include <runtime_services/realm_payload/realm_payload_test.h>
+#include <platform.h>
+#include "rmi_spm_tests.h"
+#include <smccc.h>
+#include <test_helpers.h>
 
 static test_result_t realm_multi_cpu_payload_del_undel(void);
 
@@ -29,7 +28,8 @@
 #define MAX_REPEATED_TEST 3
 
 /* Buffer to delegate and undelegate */
-static char bufferdelegate[NUM_GRANULES * GRANULE_SIZE * PLATFORM_CORE_COUNT] __aligned(GRANULE_SIZE);
+static char bufferdelegate[NUM_GRANULES * GRANULE_SIZE * PLATFORM_CORE_COUNT]
+	__aligned(GRANULE_SIZE);
 static char bufferstate[NUM_GRANULES * PLATFORM_CORE_COUNT];
 static int cpu_test_spm_rmi[PLATFORM_CORE_COUNT];
 static event_t cpu_booted[PLATFORM_CORE_COUNT];
@@ -89,10 +89,12 @@
 
 	for (int i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
 		if ((rand() % 2) == 0) {
-			retrmm = realm_granule_delegate((u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
+			retrmm = rmi_granule_delegate(
+				(u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
 			bufferstate[i] = B_DELEGATED;
 			if (retrmm != 0UL) {
-				tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
+				tftf_testcase_printf("Delegate operation\
+				returns fail, %lx\n", retrmm);
 				return TEST_RESULT_FAIL;
 			}
 		} else {
@@ -106,9 +108,9 @@
 {
 	u_register_t retrmm;
 
-	for (uint32_t i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
+	for (uint32_t i = 0U; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
 		if (bufferstate[i] == B_DELEGATED) {
-			retrmm = realm_granule_undelegate(
+			retrmm = rmi_granule_undelegate(
 				(u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
 			if (retrmm != 0UL) {
 				ERROR("Undelegate operation returns fail, %lx\n",
@@ -129,7 +131,9 @@
 static test_result_t wait_then_call(test_result_t (*callback)(void))
 {
 	unsigned int mpidr, this_mpidr = read_mpidr_el1() & MPID_MASK;
-	unsigned int cpu_node, core_pos, this_core_pos = platform_get_core_pos(this_mpidr);
+	unsigned int cpu_node, core_pos;
+	unsigned int this_core_pos = platform_get_core_pos(this_mpidr);
+
 	tftf_send_event_to_all(&cpu_booted[this_core_pos]);
 	for_each_cpu(cpu_node) {
 		mpidr = tftf_get_mpidr_from_node(cpu_node);
@@ -252,7 +256,8 @@
 		ffa_ret = cactus_echo_send_cmd(HYP_ID, SP_ID(3), ECHO_VAL3);
 		if ((ffa_func_id(ffa_ret) == FFA_ERROR) &&
 		    (ffa_error_code(ffa_ret) == FFA_ERROR_BUSY)) {
-			VERBOSE("%s(%u) trial %u\n", __func__, core_pos, trial_loop);
+			VERBOSE("%s(%u) trial %u\n", __func__,
+			core_pos, trial_loop);
 			waitms(1);
 			continue;
 		}
@@ -277,7 +282,7 @@
 /*
  * Secondary core will perform sequentially a call to secure and realm worlds.
  */
-test_result_t non_secure_call_secure_and_realm(void)
+static test_result_t non_secure_call_secure_and_realm(void)
 {
 	test_result_t result = run_spm_direct_message();
 	if (result != TEST_RESULT_SUCCESS)
@@ -310,18 +315,19 @@
 
 	for (int i = 0; i < NUM_GRANULES; i++) {
 		if (bufferstate[((cpu_node * NUM_GRANULES) + i)] == B_UNDELEGATED) {
-			retrmm = realm_granule_delegate((u_register_t)
+			retrmm = rmi_granule_delegate((u_register_t)
 					&bufferdelegate[((cpu_node *
 						NUM_GRANULES) + i) * GRANULE_SIZE]);
 			bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_DELEGATED;
 		} else {
-			retrmm = realm_granule_undelegate((u_register_t)
+			retrmm = rmi_granule_undelegate((u_register_t)
 					&bufferdelegate[((cpu_node *
 						NUM_GRANULES) + i) * GRANULE_SIZE]);
 			bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_UNDELEGATED;
 		}
 		if (retrmm != 0UL) {
-			tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
+			tftf_testcase_printf("Delegate operation returns fail, %lx\n",
+			retrmm);
 			return TEST_RESULT_FAIL;
 		}
 	}
@@ -423,7 +429,8 @@
 	 * Main test to run both SPM and RMM or TRP together in parallel
 	 */
 	for (int i = 0; i < MAX_REPEATED_TEST; i++) {
-		VERBOSE("Main test(%d) to run both SPM and RMM or TRP together in parallel...\n", i);
+		VERBOSE("Main test(%d) to run both SPM and RMM or\
+		TRP together in parallel...\n", i);
 
 		/* Reinitialize all CPUs event */
 		for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
new file mode 100644
index 0000000..562e9b8
--- /dev/null
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <arch_features.h>
+#include <debug.h>
+#include <host_realm_helper.h>
+#include <host_realm_mem_layout.h>
+#include <host_shared_data.h>
+
+#define SLEEP_TIME_MS	200U
+/*
+ * @Test_Aim@ Test realm payload creation and execution
+ */
+test_result_t test_realm_create_enter(void)
+{
+	bool ret1, ret2;
+	u_register_t retrmm;
+
+	if (get_armv9_2_feat_rme_support() == 0U) {
+		INFO("platform doesn't support RME\n");
+		return TEST_RESULT_SKIPPED;
+	}
+
+	retrmm = rmi_version();
+	VERBOSE("RMM version is: %lu.%lu\n",
+			RMI_ABI_VERSION_GET_MAJOR(retrmm),
+			RMI_ABI_VERSION_GET_MINOR(retrmm));
+	/*
+	 * Skip the test if RMM is TRP, TRP version is always null.
+	 */
+	if (retrmm == 0UL) {
+		INFO("Test case not supported for TRP as RMM\n");
+		return TEST_RESULT_SKIPPED;
+	}
+
+	if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE,
+			(u_register_t)PAGE_POOL_BASE,
+			(u_register_t)(PAGE_POOL_MAX_SIZE +
+			NS_REALM_SHARED_MEM_SIZE),
+			(u_register_t)PAGE_POOL_MAX_SIZE)) {
+		return TEST_RESULT_FAIL;
+	}
+	if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
+			NS_REALM_SHARED_MEM_SIZE)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	realm_shared_data_set_host_val(HOST_SLEEP_INDEX, SLEEP_TIME_MS);
+	ret1 = host_enter_realm_execute(REALM_SLEEP_CMD);
+	ret2 = host_destroy_realm();
+
+	if (!ret1 || !ret2) {
+		ERROR("test_realm_create_enter create:%d destroy:%d\n",
+		ret1, ret2);
+		return TEST_RESULT_FAIL;
+	}
+	return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/runtime_services/realm_payload/realm_payload_test_helpers.c b/tftf/tests/runtime_services/realm_payload/realm_payload_test_helpers.c
deleted file mode 100644
index 49bf674..0000000
--- a/tftf/tests/runtime_services/realm_payload/realm_payload_test_helpers.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <runtime_services/realm_payload/realm_payload_test.h>
-
-u_register_t realm_version(void)
-{
-	smc_args args = { RMI_RMM_REQ_VERSION };
-	smc_ret_values ret;
-
-	ret = tftf_smc(&args);
-	return ret.ret0;
-}
-
-u_register_t realm_granule_delegate(u_register_t add)
-{
-	smc_args args = { 0 };
-	smc_ret_values ret;
-
-	args.fid = SMC_RMM_GRANULE_DELEGATE;
-	args.arg1 = add;
-
-	ret = tftf_smc(&args);
-	return ret.ret0;
-}
-
-u_register_t realm_granule_undelegate(u_register_t add)
-{
-	smc_args args = { 0 };
-	smc_ret_values ret;
-
-	args.fid = SMC_RMM_GRANULE_UNDELEGATE;
-	args.arg1 = add;
-
-	ret = tftf_smc(&args);
-	return ret.ret0;
-}
-
-u_register_t realm_create(u_register_t rd_addr, u_register_t realm_params_addr)
-{
-	smc_args args = { 0 };
-	smc_ret_values ret;
-
-	args.fid = SMC_RMM_REALM_CREATE;
-	args.arg1 = rd_addr;
-	args.arg2 = realm_params_addr;
-
-	ret = tftf_smc(&args);
-	return ret.ret0;
-}
-
-u_register_t realm_destroy(u_register_t rd_addr)
-{
-	smc_args args = { 0 };
-	smc_ret_values ret;
-
-	args.fid = SMC_RMM_REALM_DESTROY;
-	args.arg1 = rd_addr;
-
-	ret = tftf_smc(&args);
-	return ret.ret0;
-}
\ No newline at end of file
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
index 61cf2ad..e809885 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
@@ -9,9 +9,9 @@
 #include <debug.h>
 #include <ffa_endpoints.h>
 #include <ffa_svc.h>
+#include <host_realm_helper.h>
 #include <irq.h>
 #include <platform.h>
-#include <runtime_services/realm_payload/realm_payload_test.h>
 #include <smccc.h>
 #include <spm_common.h>
 #include <test_helpers.h>
@@ -71,7 +71,7 @@
 		handle, constituents[0].address);
 
 	/* Delegate the shared page to Realm. */
-	retmm = realm_granule_delegate((u_register_t)&share_page);
+	retmm = rmi_granule_delegate((u_register_t)&share_page);
 	if (retmm != 0UL) {
 		ERROR("Granule delegate failed!\n");
 		return TEST_RESULT_FAIL;
@@ -82,7 +82,7 @@
 				  handle, 0, true, 1);
 
 	/* Undelegate the shared page. */
-	retmm = realm_granule_undelegate((u_register_t)&share_page);
+	retmm = rmi_granule_undelegate((u_register_t)&share_page);
 	if (retmm != 0UL) {
 		ERROR("Granule undelegate failed!\n");
 		return TEST_RESULT_FAIL;
diff --git a/tftf/tests/tests-invalid-access.mk b/tftf/tests/tests-invalid-access.mk
index ffca79e..8202c20 100644
--- a/tftf/tests/tests-invalid-access.mk
+++ b/tftf/tests/tests-invalid-access.mk
@@ -4,11 +4,14 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+TFTF_INCLUDES +=							\
+	-Iinclude/runtime_services/host_realm_managment
+
 TESTS_SOURCES	+=	tftf/tests/misc_tests/test_invalid_access.c
 
 TESTS_SOURCES	+=							\
-	$(addprefix tftf/tests/runtime_services/realm_payload/,		\
-		realm_payload_test_helpers.c				\
+	$(addprefix tftf/tests/runtime_services/host_realm_managment/,	\
+		host_realm_rmi.c					\
 	)
 
 TESTS_SOURCES	+=							\
@@ -17,4 +20,4 @@
 		ffa_helpers.c						\
 		spm_common.c						\
 		test_ffa_setup_and_discovery.c				\
-)
+)
\ No newline at end of file
diff --git a/tftf/tests/tests-realm-payload.mk b/tftf/tests/tests-realm-payload.mk
index a8642fa..6d23e38 100644
--- a/tftf/tests/tests-realm-payload.mk
+++ b/tftf/tests/tests-realm-payload.mk
@@ -1,24 +1,26 @@
 #
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+TFTF_INCLUDES +=							\
+	-Iinclude/runtime_services/host_realm_managment
+
 TESTS_SOURCES	+=							\
 	$(addprefix tftf/tests/runtime_services/realm_payload/,		\
-		realm_payload_test_helpers.c				\
-		realm_payload_test.c					\
-		realm_payload_spm_test.c				\
+		host_realm_payload_tests.c				\
 	)
 
 TESTS_SOURCES	+=							\
-	$(addprefix tftf/tests/runtime_services/secure_service/,	\
-		ffa_helpers.c						\
-		spm_common.c						\
-		test_ffa_direct_messaging.c				\
-		test_ffa_interrupts.c					\
-		test_ffa_memory_sharing.c				\
-		test_ffa_setup_and_discovery.c				\
-		test_spm_cpu_features.c					\
-		test_spm_smmu.c						\
+	$(addprefix tftf/tests/runtime_services/host_realm_managment/,	\
+		host_realm_rmi.c					\
+		host_realm_helper.c					\
+		host_shared_data.c					\
+		rmi_delegate_tests.c					\
 	)
+
+TESTS_SOURCES	+=							\
+	$(addprefix lib/heap/,						\
+		page_alloc.c						\
+	)
\ No newline at end of file
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index f80ead6..8438ea1 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -7,15 +7,18 @@
 -->
 
 <testsuites>
-
-  <testsuite name="Realm payload tests" description="Tests for Realm management interface">
-	  <testcase name="Realm payload boot" function="realm_version_single_cpu" />
-	  <testcase name="Realm payload multi CPU request" function="realm_version_multi_cpu" />
-	  <testcase name="Realm payload Delegate and Undelegate" function="realm_delegate_undelegate" />
-	  <testcase name="Multi CPU Realm payload Delegate and Undelegate" function="realm_delundel_multi_cpu" />
-	  <testcase name="Testing delegation fails" function="realm_fail_del" />
-	  <testcase name="Test TFTF can call RMM/TRP and SPM serially on a single core" function="test_spm_rmm_serial_smc" />
-	  <testcase name="Test TFTF can call RMM/TRP and SPM parallelly on a multi core" function="test_spm_rmm_parallel_smc" />
+  <testsuite name="Realm payload at EL1" description="Test Realm EL1 framework capabilities" >
+	  <testcase name="Realm EL1 creation and execution test"
+	  function="test_realm_create_enter" />
+	  <testcase name="Realm payload boot"
+	  function="realm_version_single_cpu" />
+	  <testcase name="Realm payload multi CPU request"
+	  function="realm_version_multi_cpu" />
+	  <testcase name="Realm payload Delegate and Undelegate"
+	  function="realm_delegate_undelegate" />
+	  <testcase name="Multi CPU Realm payload Delegate and Undelegate"
+	  function="realm_delundel_multi_cpu" />
+	  <testcase name="Testing delegation fails"
+	  function="realm_fail_del" />
   </testsuite>
-
 </testsuites>
diff --git a/tftf/tests/tests-rmi-spm.mk b/tftf/tests/tests-rmi-spm.mk
new file mode 100644
index 0000000..960aa93
--- /dev/null
+++ b/tftf/tests/tests-rmi-spm.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TFTF_INCLUDES +=							\
+	-Iinclude/runtime_services/host_realm_managment
+
+TESTS_SOURCES	+=							\
+	$(addprefix tftf/tests/runtime_services/host_realm_managment/,	\
+		host_realm_rmi.c					\
+		rmi_spm_tests.c						\
+	)
+
+TESTS_SOURCES	+=							\
+	$(addprefix tftf/tests/runtime_services/secure_service/,	\
+		${ARCH}/ffa_arch_helpers.S				\
+		ffa_helpers.c						\
+		spm_common.c						\
+	)
+
+TESTS_SOURCES	+=							\
+	$(addprefix lib/heap/,						\
+		page_alloc.c						\
+	)
\ No newline at end of file
diff --git a/tftf/tests/tests-rmi-spm.xml b/tftf/tests/tests-rmi-spm.xml
new file mode 100644
index 0000000..1d12b4a
--- /dev/null
+++ b/tftf/tests/tests-rmi-spm.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+
+  SPDX-License-Identifier: BSD-3-Clause
+-->
+
+<testsuites>
+
+  <testsuite name="RMI and SPM tests" description="Tests for SPM and RMI delegate/undelegate">
+	  <testcase name="Test TFTF can call RMM/TRP and SPM serially on a single core"
+	  function="test_spm_rmm_serial_smc" />
+	  <testcase name="Test TFTF can call RMM/TRP and SPM parallelly on a multi core"
+	  function="test_spm_rmm_parallel_smc" />
+  </testsuite>
+
+</testsuites>
\ No newline at end of file
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index 5d71aec..f2ad0e4 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -3,6 +3,10 @@
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
+
+TFTF_INCLUDES +=							\
+	-Iinclude/runtime_services/host_realm_managment
+
 TESTS_SOURCES	+=							\
 	$(addprefix tftf/tests/runtime_services/secure_service/,	\
 		${ARCH}/ffa_arch_helpers.S				\
@@ -21,6 +25,6 @@
 	)
 
 TESTS_SOURCES	+=							\
-	$(addprefix tftf/tests/runtime_services/realm_payload/,		\
-		realm_payload_test_helpers.c				\
-	)
+	$(addprefix tftf/tests/runtime_services/host_realm_managment/,	\
+		host_realm_rmi.c					\
+	)
\ No newline at end of file
diff --git a/tftf/tests/tests-standard.mk b/tftf/tests/tests-standard.mk
index a722077..d57c381 100644
--- a/tftf/tests/tests-standard.mk
+++ b/tftf/tests/tests-standard.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -22,7 +22,8 @@
 	tests-trng.mk				\
 	tests-tsp.mk				\
 	tests-uncontainable.mk			\
-	tests-debugfs.mk                        \
+	tests-debugfs.mk			\
+	tests-rmi-spm.mk			\
 	tests-realm-payload.mk			\
 )
 
diff --git a/tftf/tests/tests-standard.xml b/tftf/tests/tests-standard.xml
index 384a5f4..1917bc9 100644
--- a/tftf/tests/tests-standard.xml
+++ b/tftf/tests/tests-standard.xml
@@ -24,6 +24,7 @@
   <!ENTITY tests-spm SYSTEM "tests-spm.xml">
   <!ENTITY tests-pmu-leakage SYSTEM "tests-pmu-leakage.xml">
   <!ENTITY tests-debugfs SYSTEM "tests-debugfs.xml">
+  <!ENTITY tests-rmi-spm SYSTEM "tests-rmi-spm.xml">
   <!ENTITY tests-realm-payload SYSTEM "tests-realm-payload.xml">
 ]>
 
@@ -44,6 +45,7 @@
   &tests-spm;
   &tests-pmu-leakage;
   &tests-debugfs;
+  &tests-rmi-spm;
   &tests-realm-payload;
 
 </testsuites>