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/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;
+}