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