blob: 9a604c6fc3b886d9d99a86807ba0c14db569ce2e [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>
Shruti Gupta91105082024-11-27 05:29:55 +000014#include <realm_psi.h>
Shruti Gupta5abab762024-11-27 04:57:53 +000015#include <realm_rsi.h>
16#include <sync.h>
17
Shruti Gupta91105082024-11-27 05:29:55 +000018static bool is_plane0;
19static unsigned int plane_num;
20
21bool realm_is_plane0(void)
22{
23 return is_plane0;
24}
25
26unsigned int realm_get_my_plane_num(void)
27{
28 return plane_num;
29}
Shruti Gupta5abab762024-11-27 04:57:53 +000030
31void realm_plane_init(void)
32{
33 u_register_t ret;
34
35 ret = rsi_get_version(RSI_ABI_VERSION_VAL);
36 if (ret == RSI_ERROR_STATE) {
37 is_plane0 = false;
Shruti Gupta91105082024-11-27 05:29:55 +000038 plane_num = (unsigned int)psi_get_plane_id();
Shruti Gupta5abab762024-11-27 04:57:53 +000039 } else {
40 is_plane0 = true;
Shruti Gupta91105082024-11-27 05:29:55 +000041 plane_num = PRIMARY_PLANE_ID;
Shruti Gupta5abab762024-11-27 04:57:53 +000042 }
43}
44
45static void restore_plane_context(rsi_plane_run *run)
46{
47 for (unsigned int i = 0U; i < RSI_PLANE_NR_GPRS; i++) {
48 run->enter.gprs[i] = run->exit.gprs[i];
49 }
50
51 run->enter.pc = run->exit.elr;
52}
53
Shruti Gupta91105082024-11-27 05:29:55 +000054static u_register_t realm_exit_to_host_as_plane_n(enum host_call_cmd exit_code,
55 u_register_t plane_num)
56{
57 struct rsi_host_call host_cal __aligned(sizeof(struct rsi_host_call));
58 smc_ret_values res = {};
59
60 assert(realm_is_p0());
61 host_cal.imm = exit_code;
62 host_cal.gprs[0] = plane_num;
63 host_cal.gprs[1] = read_mpidr_el1();
64 res = tftf_smc(&(smc_args) {RSI_HOST_CALL, (u_register_t)&host_cal,
65 0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
66 return res.ret0;
67}
68
Shruti Gupta5abab762024-11-27 04:57:53 +000069/* return true to re-enter PlaneN, false to exit to P0 */
Shruti Guptaa0736c32024-11-27 09:34:35 +000070u_register_t handle_plane_exit(u_register_t plane_index,
Shruti Gupta5abab762024-11-27 04:57:53 +000071 u_register_t perm_index,
72 rsi_plane_run *run)
73{
74 u_register_t ec = EC_BITS(run->exit.esr);
Shruti Gupta91105082024-11-27 05:29:55 +000075 u_register_t ret;
Shruti Gupta5abab762024-11-27 04:57:53 +000076
Shruti Guptaa0736c32024-11-27 09:34:35 +000077 if (((run->exit.esr & ISS_FSC_MASK) >= FSC_L0_PERM_FAULT) &&
78 ((run->exit.esr & ISS_FSC_MASK) <= FSC_L3_PERM_FAULT)) {
79
80 /* If Plane N exit is due to permission fault, change s2ap */
81 u_register_t base, new_base, response, ret;
82 u_register_t new_cookie = 0UL;
83
84 new_base = base = (run->exit.far & ~PAGE_SIZE_MASK);
85
86 VERBOSE("P0 set s2ap 0x%lx\n", base);
87 while (new_base != (base + PAGE_SIZE)) {
88
89 ret = rsi_mem_set_perm_index(new_base, base + PAGE_SIZE,
90 perm_index, new_cookie, &new_base,
91 &response, &new_cookie);
92
93 if (ret != RSI_SUCCESS || response == RSI_REJECT) {
94 ERROR("rsi_mem_set_perm_index failed 0x%lx\n", new_base);
95 return PSI_RETURN_TO_P0;
96 }
97 }
98
99 restore_plane_context(run);
100 return PSI_RETURN_TO_PN;
101 }
102
Shruti Gupta5abab762024-11-27 04:57:53 +0000103 /* Disallow SMC from Plane N */
104 if (ec == EC_AARCH64_SMC) {
Shruti Guptaa0736c32024-11-27 09:34:35 +0000105 /* TODO Support PSCI in future */
Shruti Gupta5abab762024-11-27 04:57:53 +0000106 restore_plane_context(run);
107 run->enter.gprs[0] = RSI_ERROR_STATE;
Shruti Guptaa0736c32024-11-27 09:34:35 +0000108 return PSI_RETURN_TO_PN;
Shruti Gupta5abab762024-11-27 04:57:53 +0000109 }
Shruti Gupta91105082024-11-27 05:29:55 +0000110
111 /* Handle PSI HVC call from Plane N */
112 if (ec == EC_AARCH64_HVC) {
113 u_register_t hvc_id = run->exit.gprs[0];
114
115 restore_plane_context(run);
116 switch (hvc_id) {
117 case PSI_CALL_GET_SHARED_BUFF_CMD:
118 run->enter.gprs[0] = RSI_SUCCESS;
119 run->enter.gprs[1] = (u_register_t)realm_get_my_shared_structure();
Shruti Guptaa0736c32024-11-27 09:34:35 +0000120 return PSI_RETURN_TO_PN;
Shruti Gupta91105082024-11-27 05:29:55 +0000121 case PSI_CALL_GET_PLANE_ID_CMD:
122 run->enter.gprs[0] = RSI_SUCCESS;
123 run->enter.gprs[1] = plane_index;
Shruti Guptaa0736c32024-11-27 09:34:35 +0000124 return PSI_RETURN_TO_PN;
Shruti Gupta91105082024-11-27 05:29:55 +0000125 case PSI_CALL_EXIT_PRINT_CMD:
126 /* exit to host to flush buffer, then return to PN */
127 ret = realm_exit_to_host_as_plane_n(HOST_CALL_EXIT_PRINT_CMD, plane_index);
128 run->enter.gprs[0] = ret;
Shruti Guptaa0736c32024-11-27 09:34:35 +0000129 return PSI_RETURN_TO_PN;
Shruti Gupta91105082024-11-27 05:29:55 +0000130 case PSI_P0_CALL:
131 default:
Shruti Guptaa0736c32024-11-27 09:34:35 +0000132 return PSI_RETURN_TO_P0;
Shruti Gupta91105082024-11-27 05:29:55 +0000133 }
134 }
Shruti Guptaa0736c32024-11-27 09:34:35 +0000135 return PSI_RETURN_TO_P0;
Shruti Gupta5abab762024-11-27 04:57:53 +0000136}
137
138static bool plane_common_init(u_register_t plane_index,
139 u_register_t perm_index,
140 u_register_t base,
141 rsi_plane_run *run)
142{
143 u_register_t ret;
144
145 memset(run, 0, sizeof(rsi_plane_run));
146 run->enter.pc = base;
147
148 /* Perm init */
149 ret = rsi_mem_set_perm_value(plane_index, perm_index, PERM_LABEL_RW_upX);
150 if (ret != RSI_SUCCESS) {
151 ERROR("rsi_mem_set_perm_value failed %u\n", plane_index);
152 return false;
153 }
154 return true;
155}
156
157bool realm_plane_enter(u_register_t plane_index,
158 u_register_t perm_index,
159 u_register_t base,
160 u_register_t flags,
161 rsi_plane_run *run)
162{
163 u_register_t ret;
164 bool ret1;
165
166 ret1 = plane_common_init(plane_index, perm_index, base, run);
167 if (!ret1) {
168 return ret1;
169 }
170
171 run->enter.flags = flags;
172
Shruti Guptaa0736c32024-11-27 09:34:35 +0000173 while (true) {
Shruti Gupta5abab762024-11-27 04:57:53 +0000174 ret = rsi_plane_enter(plane_index, (u_register_t)run);
175 if (ret != RSI_SUCCESS) {
176 ERROR("Plane %u enter failed ret= 0x%lx\n", plane_index, ret);
177 return false;
178 }
179
180 VERBOSE("plane exit_reason=0x%lx esr=0x%lx hpfar=0x%lx far=0x%lx\n",
181 run->exit.exit_reason,
182 run->exit.esr,
183 run->exit.hpfar,
184 run->exit.far);
185
Shruti Guptaa0736c32024-11-27 09:34:35 +0000186 ret = handle_plane_exit(plane_index, perm_index, run);
187
188 if (ret != PSI_RETURN_TO_PN) {
189 return true;
190 }
Shruti Gupta5abab762024-11-27 04:57:53 +0000191 }
Shruti Gupta5abab762024-11-27 04:57:53 +0000192}
193