blob: ef1e0ab5870058de559c188f0bd90de4b04db681 [file] [log] [blame]
Shruti Gupta5abab762024-11-27 04:57:53 +00001/*
2 * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7#include <stdio.h>
8#include <arch.h>
9#include <arch_features.h>
10#include <assert.h>
11#include <debug.h>
12
13#include <host_realm_helper.h>
14#include <realm_rsi.h>
15#include <sync.h>
16
17bool is_plane0;
18
19void realm_plane_init(void)
20{
21 u_register_t ret;
22
23 ret = rsi_get_version(RSI_ABI_VERSION_VAL);
24 if (ret == RSI_ERROR_STATE) {
25 is_plane0 = false;
26 } else {
27 is_plane0 = true;
28 }
29}
30
31static void restore_plane_context(rsi_plane_run *run)
32{
33 for (unsigned int i = 0U; i < RSI_PLANE_NR_GPRS; i++) {
34 run->enter.gprs[i] = run->exit.gprs[i];
35 }
36
37 run->enter.pc = run->exit.elr;
38}
39
40/* return true to re-enter PlaneN, false to exit to P0 */
41static bool handle_plane_exit(u_register_t plane_index,
42 u_register_t perm_index,
43 rsi_plane_run *run)
44{
45 u_register_t ec = EC_BITS(run->exit.esr);
46
47 /* Disallow SMC from Plane N */
48 if (ec == EC_AARCH64_SMC) {
49 restore_plane_context(run);
50 run->enter.gprs[0] = RSI_ERROR_STATE;
51 return true;
52 }
53 return false;
54}
55
56static bool plane_common_init(u_register_t plane_index,
57 u_register_t perm_index,
58 u_register_t base,
59 rsi_plane_run *run)
60{
61 u_register_t ret;
62
63 memset(run, 0, sizeof(rsi_plane_run));
64 run->enter.pc = base;
65
66 /* Perm init */
67 ret = rsi_mem_set_perm_value(plane_index, perm_index, PERM_LABEL_RW_upX);
68 if (ret != RSI_SUCCESS) {
69 ERROR("rsi_mem_set_perm_value failed %u\n", plane_index);
70 return false;
71 }
72 return true;
73}
74
75bool realm_plane_enter(u_register_t plane_index,
76 u_register_t perm_index,
77 u_register_t base,
78 u_register_t flags,
79 rsi_plane_run *run)
80{
81 u_register_t ret;
82 bool ret1;
83
84 ret1 = plane_common_init(plane_index, perm_index, base, run);
85 if (!ret1) {
86 return ret1;
87 }
88
89 run->enter.flags = flags;
90
91 while (ret1) {
92 ret = rsi_plane_enter(plane_index, (u_register_t)run);
93 if (ret != RSI_SUCCESS) {
94 ERROR("Plane %u enter failed ret= 0x%lx\n", plane_index, ret);
95 return false;
96 }
97
98 VERBOSE("plane exit_reason=0x%lx esr=0x%lx hpfar=0x%lx far=0x%lx\n",
99 run->exit.exit_reason,
100 run->exit.esr,
101 run->exit.hpfar,
102 run->exit.far);
103
104 ret1 = handle_plane_exit(plane_index, perm_index, run);
105 }
106 return true;
107}
108