blob: 95bb6f13e545300600d6c885eafdfcf686829477 [file] [log] [blame]
Shruti Gupta24597d12023-10-02 10:40:19 +01001/*
2 * Copyright (c) 2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <stdio.h>
9
10#include <arch_features.h>
11#include <arch_helpers.h>
12#include <debug.h>
13#include <fpu.h>
14#include <host_realm_helper.h>
15#include <host_shared_data.h>
16#include <psci.h>
17#include "realm_def.h"
Shruti Guptabd729192025-01-24 17:02:15 +000018#include <realm_helpers.h>
19#include <realm_psi.h>
Shruti Gupta24597d12023-10-02 10:40:19 +010020#include <realm_rsi.h>
21#include <realm_tests.h>
22#include <realm_psci.h>
23#include <tftf_lib.h>
24
Shruti Guptabd729192025-01-24 17:02:15 +000025#define CXT_ID_MAGIC 0x100
26#define P1_CXT_ID_MAGIC 0x200
27
Shruti Gupta24597d12023-10-02 10:40:19 +010028static uint64_t is_secondary_cpu_booted;
Shruti Guptaaffbae82023-08-22 12:51:11 +010029static spinlock_t lock;
Shruti Guptabd729192025-01-24 17:02:15 +000030static rsi_plane_run run[MAX_REC_COUNT] __aligned(PAGE_SIZE);
31static u_register_t base, plane_index, perm_index;
Shruti Gupta24597d12023-10-02 10:40:19 +010032
Shruti Guptabd729192025-01-24 17:02:15 +000033static void plane0_recn_handler(u_register_t cxt_id)
Shruti Gupta24597d12023-10-02 10:40:19 +010034{
Shruti Guptabd729192025-01-24 17:02:15 +000035 uint64_t rec = 0U;
36
37 realm_printf("running on Rec= 0x%lx cxt_id= 0x%lx\n",
Shruti Gupta24597d12023-10-02 10:40:19 +010038 read_mpidr_el1() & MPID_MASK, cxt_id);
39 if (cxt_id < CXT_ID_MAGIC || cxt_id > CXT_ID_MAGIC + MAX_REC_COUNT) {
Shruti Guptaa276b202023-12-18 10:07:43 +000040 realm_printf("Wrong cxt_id\n");
Shruti Gupta24597d12023-10-02 10:40:19 +010041 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
42 }
Shruti Guptaaffbae82023-08-22 12:51:11 +010043 spin_lock(&lock);
Shruti Gupta24597d12023-10-02 10:40:19 +010044 is_secondary_cpu_booted++;
Shruti Guptabd729192025-01-24 17:02:15 +000045 rec = read_mpidr_el1() & MPID_MASK;
46 spin_unlock(&lock);
47
48 /* enter plane */
49 u_register_t flags = 0U;
50
51 /* Use Base adr, plane_index, perm_index programmed by P0 rec0 */
52 run[rec].enter.pc = base;
53 realm_printf("Entering plane %ld, ep=0x%lx rec=0x%lx\n", plane_index, base, rec);
54 realm_plane_enter(plane_index, perm_index, base, flags, &run[rec]);
55
56 if (run[rec].exit.gprs[0] == SMC_PSCI_CPU_OFF) {
57 realm_printf("Plane N did not request CPU OFF\n");
58 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
59 }
60 realm_cpu_off();
61}
62
63static void recn_handler(u_register_t cxt_id)
64{
65 realm_printf("running on Rec= 0x%lx cxt_id= 0x%lx\n",
66 read_mpidr_el1() & MPID_MASK, cxt_id);
67
68 if (cxt_id < P1_CXT_ID_MAGIC || cxt_id > P1_CXT_ID_MAGIC + MAX_REC_COUNT) {
69 realm_printf("Wrong cxt_id\n");
70 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
71 }
72 spin_lock(&lock);
73 is_secondary_cpu_booted++;
Shruti Guptaaffbae82023-08-22 12:51:11 +010074 spin_unlock(&lock);
Shruti Gupta24597d12023-10-02 10:40:19 +010075 realm_cpu_off();
76}
77
78static void rec2_handler(u_register_t cxt_id)
79{
80 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
81}
82
83bool test_realm_multiple_rec_psci_denied_cmd(void)
84{
85 u_register_t ret;
86
87 is_secondary_cpu_booted = 0U;
Shruti Guptabd729192025-01-24 17:02:15 +000088 ret = realm_cpu_on(1U, (uintptr_t)recn_handler, 0x100);
Shruti Gupta24597d12023-10-02 10:40:19 +010089 if (ret != PSCI_E_DENIED) {
90 return false;
91 }
92
93 if (is_secondary_cpu_booted != 0U) {
94 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
95 }
96
97 ret = realm_psci_affinity_info(1U, MPIDR_AFFLVL0);
98 if (ret != PSCI_STATE_OFF) {
99 realm_printf("CPU 1 should have been off\n");
100 return false;
101 }
102
103 ret = realm_cpu_on(2U, (uintptr_t)rec2_handler, 0x102);
104 if (ret != PSCI_E_ALREADY_ON) {
105 realm_printf("CPU 2 should have been already on\n");
106 return false;
107 }
108 return true;
109}
Shruti Guptaaffbae82023-08-22 12:51:11 +0100110
Shruti Guptabd729192025-01-24 17:02:15 +0000111/*
112 * All Planes enter this test function.
113 * P0 Rec0 Enters Plane N
114 * Plane N rec 0 requests CPU ON for all other rec
115 * P0 Rec0 requests CPU ON to host
116 * Host enters P0 RecN from different CPU
117 * P0 RecN enters PlaneN RecN
118 * Rec N requests CPU OFF, exits to P0
119 * P0 requests CPU OFF to host.
120 * P0 verifies all other CPU are off.
121 */
122bool test_realm_multiple_plane_multiple_rec_multiple_cpu_cmd(void)
123{
124 unsigned int i = 1U, rec_count;
125 u_register_t ret;
126 bool ret1;
127
128 realm_printf("Realm: running on Rec= 0x%lx\n", read_mpidr_el1() & MPID_MASK);
129 rec_count = realm_shared_data_get_my_host_val(HOST_ARG3_INDEX);
130
131 /* Check CPU_ON is supported */
132 ret = realm_psci_features(SMC_PSCI_CPU_ON);
133 if (ret != PSCI_E_SUCCESS) {
134 realm_printf("SMC_PSCI_CPU_ON not supported\n");
135 return false;
136 }
137
138 if (realm_is_plane0()) {
139 /* Plane 0 all rec */
140 u_register_t flags = 0U;
141
142 plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
143 base = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
144 perm_index = plane_index + 1U;
145
146 plane_common_init(plane_index, perm_index, base, &run[0U]);
147
148 ret1 = realm_plane_enter(plane_index, perm_index, base, flags, &run[0U]);
149 while (ret1 && run->exit.gprs[0] == SMC_PSCI_CPU_ON_AARCH64) {
150 realm_printf("Plane N requested CPU on Rec=0x%lx\n", run[0].exit.gprs[1]);
151
152 /* Pass context tp RecN - CXT + rec idx */
153 run[0].enter.gprs[0] = realm_cpu_on(run[0].exit.gprs[1],
154 (uintptr_t)plane0_recn_handler,
155 CXT_ID_MAGIC + run[0].exit.gprs[1]);
156
157 /* re-enter plane N 1 to complete cpu on */
158 ret1 = realm_plane_enter(plane_index, perm_index, base, flags, &run[0U]);
159 if (!ret1) {
160 realm_printf("PlaneN CPU on complete failed\n");
161 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
162 }
163 }
164
165 /* wait for all CPUs to come up */
166 while (is_secondary_cpu_booted != rec_count - 1U) {
167 waitms(200);
168 }
169
170 /* wait for all CPUs to turn off */
171 while (i < rec_count) {
172 ret = realm_psci_affinity_info(i, MPIDR_AFFLVL0);
173 if (ret != PSCI_STATE_OFF) {
174 /* wait and query again */
175 realm_printf(" CPU %d is not off\n", i);
176 waitms(200);
177 continue;
178 }
179 i++;
180 }
181 realm_printf("All CPU are off\n");
182 return true;
183 } else {
184 /* Plane 1 Rec 0 */
185 for (unsigned int j = 1U; j < rec_count; j++) {
186 realm_printf("CPU ON Rec=%u\n", j);
187 ret = realm_cpu_on(j, (uintptr_t)recn_handler, P1_CXT_ID_MAGIC + j);
188 if (ret != PSCI_E_SUCCESS) {
189 realm_printf("SMC_PSCI_CPU_ON failed %d.\n", j);
190 return false;
191 }
192 }
193 /* Exit to Host to allow host to run all CPUs */
194 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
195
196 /* wait for all CPUs to come up */
197 while (is_secondary_cpu_booted != rec_count - 1U) {
198 waitms(200);
199 }
200 return true;
201 }
202 return true;
203}
204
Shruti Guptaaffbae82023-08-22 12:51:11 +0100205bool test_realm_multiple_rec_multiple_cpu_cmd(void)
206{
207 unsigned int i = 1U, rec_count;
208 u_register_t ret;
209
Shruti Guptabd729192025-01-24 17:02:15 +0000210 realm_printf("Realm: running on Rec= 0x%lx\n", read_mpidr_el1() & MPID_MASK);
Shruti Guptaaffbae82023-08-22 12:51:11 +0100211 rec_count = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
212
213 /* Check CPU_ON is supported */
214 ret = realm_psci_features(SMC_PSCI_CPU_ON);
215 if (ret != PSCI_E_SUCCESS) {
216 realm_printf("SMC_PSCI_CPU_ON not supported\n");
217 return false;
218 }
219
220 for (unsigned int j = 1U; j < rec_count; j++) {
Shruti Guptabd729192025-01-24 17:02:15 +0000221 ret = realm_cpu_on(j, (uintptr_t)recn_handler, P1_CXT_ID_MAGIC + j);
Shruti Guptaaffbae82023-08-22 12:51:11 +0100222 if (ret != PSCI_E_SUCCESS) {
223 realm_printf("SMC_PSCI_CPU_ON failed %d.\n", j);
224 return false;
225 }
226 }
227
228 /* Exit to host to allow host to run all CPUs */
229 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
230 /* wait for all CPUs to come up */
231 while (is_secondary_cpu_booted != rec_count - 1U) {
232 waitms(200);
233 }
234
235 /* wait for all CPUs to turn off */
236 while (i < rec_count) {
237 ret = realm_psci_affinity_info(i, MPIDR_AFFLVL0);
238 if (ret != PSCI_STATE_OFF) {
239 /* wait and query again */
240 realm_printf(" CPU %d is not off\n", i);
241 waitms(200);
242 continue;
243 }
244 i++;
245 }
246 realm_printf("All CPU are off\n");
247 return true;
248}