Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 1 | /* |
| 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 Gupta | bd72919 | 2025-01-24 17:02:15 +0000 | [diff] [blame] | 18 | #include <realm_helpers.h> |
| 19 | #include <realm_psi.h> |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 20 | #include <realm_rsi.h> |
| 21 | #include <realm_tests.h> |
| 22 | #include <realm_psci.h> |
| 23 | #include <tftf_lib.h> |
| 24 | |
Shruti Gupta | bd72919 | 2025-01-24 17:02:15 +0000 | [diff] [blame] | 25 | #define CXT_ID_MAGIC 0x100 |
| 26 | #define P1_CXT_ID_MAGIC 0x200 |
| 27 | |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 28 | static uint64_t is_secondary_cpu_booted; |
Shruti Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 29 | static spinlock_t lock; |
Shruti Gupta | bd72919 | 2025-01-24 17:02:15 +0000 | [diff] [blame] | 30 | static rsi_plane_run run[MAX_REC_COUNT] __aligned(PAGE_SIZE); |
| 31 | static u_register_t base, plane_index, perm_index; |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 32 | |
Shruti Gupta | bd72919 | 2025-01-24 17:02:15 +0000 | [diff] [blame] | 33 | static void plane0_recn_handler(u_register_t cxt_id) |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 34 | { |
Shruti Gupta | bd72919 | 2025-01-24 17:02:15 +0000 | [diff] [blame] | 35 | uint64_t rec = 0U; |
| 36 | |
| 37 | realm_printf("running on Rec= 0x%lx cxt_id= 0x%lx\n", |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 38 | read_mpidr_el1() & MPID_MASK, cxt_id); |
| 39 | if (cxt_id < CXT_ID_MAGIC || cxt_id > CXT_ID_MAGIC + MAX_REC_COUNT) { |
Shruti Gupta | a276b20 | 2023-12-18 10:07:43 +0000 | [diff] [blame] | 40 | realm_printf("Wrong cxt_id\n"); |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 41 | rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD); |
| 42 | } |
Shruti Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 43 | spin_lock(&lock); |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 44 | is_secondary_cpu_booted++; |
Shruti Gupta | bd72919 | 2025-01-24 17:02:15 +0000 | [diff] [blame] | 45 | 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 | |
| 63 | static 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 Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 74 | spin_unlock(&lock); |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 75 | realm_cpu_off(); |
| 76 | } |
| 77 | |
| 78 | static void rec2_handler(u_register_t cxt_id) |
| 79 | { |
| 80 | rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD); |
| 81 | } |
| 82 | |
| 83 | bool test_realm_multiple_rec_psci_denied_cmd(void) |
| 84 | { |
| 85 | u_register_t ret; |
| 86 | |
| 87 | is_secondary_cpu_booted = 0U; |
Shruti Gupta | bd72919 | 2025-01-24 17:02:15 +0000 | [diff] [blame] | 88 | ret = realm_cpu_on(1U, (uintptr_t)recn_handler, 0x100); |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 89 | 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 Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 110 | |
Shruti Gupta | bd72919 | 2025-01-24 17:02:15 +0000 | [diff] [blame] | 111 | /* |
| 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 | */ |
| 122 | bool 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 Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 205 | bool test_realm_multiple_rec_multiple_cpu_cmd(void) |
| 206 | { |
| 207 | unsigned int i = 1U, rec_count; |
| 208 | u_register_t ret; |
| 209 | |
Shruti Gupta | bd72919 | 2025-01-24 17:02:15 +0000 | [diff] [blame] | 210 | realm_printf("Realm: running on Rec= 0x%lx\n", read_mpidr_el1() & MPID_MASK); |
Shruti Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 211 | 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 Gupta | bd72919 | 2025-01-24 17:02:15 +0000 | [diff] [blame] | 221 | ret = realm_cpu_on(j, (uintptr_t)recn_handler, P1_CXT_ID_MAGIC + j); |
Shruti Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 222 | 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 | } |