feat: tftf realm extension

This patch adds Realm payload management capabilities to TFTF
to act as a NS Host, it includes creation and destruction of a Realm,
mapping of protected data and creation of all needed RTT levels,
sharing of NS memory buffer from Host to Realm by mapping of
unprotected IPA, create REC and auxiliary granules, exit Realm
using RSI_HOST_CALL ABI.

Older realm_payload name is used now for only R-EL1 test cases,
RMI and SPM test cases have been moved to new file tests-rmi-spm.

New TFTF_MAX_IMAGE_SIZE argument added to FVP platform.mk,
as an offset from where R-EL1 payload memory resources start.

Signed-off-by: Nabil Kahlouche <nabil.kahlouche@arm.com>
Change-Id: Ida4cfd334795879d55924bb33b9b77182a3dcef7
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>