test(realm): add support for RSI Planes ABI
Add Planes RSI support.
Add helpers to setup initialize and enter planes.
Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
Change-Id: I62946a185c47fe77a04f42751d0b0a467d41ceee
diff --git a/realm/realm_plane.c b/realm/realm_plane.c
new file mode 100644
index 0000000..ef1e0ab
--- /dev/null
+++ b/realm/realm_plane.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <stdio.h>
+#include <arch.h>
+#include <arch_features.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <host_realm_helper.h>
+#include <realm_rsi.h>
+#include <sync.h>
+
+bool is_plane0;
+
+void realm_plane_init(void)
+{
+ u_register_t ret;
+
+ ret = rsi_get_version(RSI_ABI_VERSION_VAL);
+ if (ret == RSI_ERROR_STATE) {
+ is_plane0 = false;
+ } else {
+ is_plane0 = true;
+ }
+}
+
+static void restore_plane_context(rsi_plane_run *run)
+{
+ for (unsigned int i = 0U; i < RSI_PLANE_NR_GPRS; i++) {
+ run->enter.gprs[i] = run->exit.gprs[i];
+ }
+
+ run->enter.pc = run->exit.elr;
+}
+
+/* return true to re-enter PlaneN, false to exit to P0 */
+static bool handle_plane_exit(u_register_t plane_index,
+ u_register_t perm_index,
+ rsi_plane_run *run)
+{
+ u_register_t ec = EC_BITS(run->exit.esr);
+
+ /* Disallow SMC from Plane N */
+ if (ec == EC_AARCH64_SMC) {
+ restore_plane_context(run);
+ run->enter.gprs[0] = RSI_ERROR_STATE;
+ return true;
+ }
+ return false;
+}
+
+static bool plane_common_init(u_register_t plane_index,
+ u_register_t perm_index,
+ u_register_t base,
+ rsi_plane_run *run)
+{
+ u_register_t ret;
+
+ memset(run, 0, sizeof(rsi_plane_run));
+ run->enter.pc = base;
+
+ /* Perm init */
+ ret = rsi_mem_set_perm_value(plane_index, perm_index, PERM_LABEL_RW_upX);
+ if (ret != RSI_SUCCESS) {
+ ERROR("rsi_mem_set_perm_value failed %u\n", plane_index);
+ return false;
+ }
+ return true;
+}
+
+bool realm_plane_enter(u_register_t plane_index,
+ u_register_t perm_index,
+ u_register_t base,
+ u_register_t flags,
+ rsi_plane_run *run)
+{
+ u_register_t ret;
+ bool ret1;
+
+ ret1 = plane_common_init(plane_index, perm_index, base, run);
+ if (!ret1) {
+ return ret1;
+ }
+
+ run->enter.flags = flags;
+
+ while (ret1) {
+ ret = rsi_plane_enter(plane_index, (u_register_t)run);
+ if (ret != RSI_SUCCESS) {
+ ERROR("Plane %u enter failed ret= 0x%lx\n", plane_index, ret);
+ return false;
+ }
+
+ VERBOSE("plane exit_reason=0x%lx esr=0x%lx hpfar=0x%lx far=0x%lx\n",
+ run->exit.exit_reason,
+ run->exit.esr,
+ run->exit.hpfar,
+ run->exit.far);
+
+ ret1 = handle_plane_exit(plane_index, perm_index, run);
+ }
+ return true;
+}
+