1 /* 2 * Copyright (c) 2023-2025, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #include <common/debug.h> 7 #include <services/el3_spmd_logical_sp.h> 8 #include <services/ffa_svc.h> 9 #include <smccc_helpers.h> 10 11 #define SPMD_LP_PARTITION_ID SPMD_LP_ID_START 12 #define SPMD_LP_UUID {0xe98e43ad, 0xb7db524f, 0x47a3bf57, 0x1588f4e3} 13 14 /* SPMD Logical SP currently only supports sending direct message. */ 15 #define SPMD_PARTITION_PROPERTIES FFA_PARTITION_DIRECT_REQ_SEND 16 17 #define SPMD_LP_MAX_SUPPORTED_SP 10 18 19 static void fvp_get_partition_info(void) 20 { 21 /* 22 * This helper invokes FFA_PARTITION_INFO_GET_REGS to obtain partition 23 * properties of Secure Partitions managed by SPMC. This happens even 24 * before the normal world is booted. Hafnium SPMC mistakes this as a 25 * FF-A invocation from NWd. As per FF-A version negotiation protocol, 26 * Hafnium locks the version of NWd to v1.3 whereas the NWd never got 27 * an opportunity to register its own framework version. 28 * 29 * This patch performs early exit from the helper utility to give NWd 30 * endpoint/Hypervisor an opportunity to register its FF-A version with 31 * SPM. 32 * 33 * TODO: Integrate this helper function for a new anticipated feature. 34 */ 35 return; 36 37 struct ffa_value ret = { 0 }; 38 uint32_t target_uuid[4] = { 0 }; 39 static struct ffa_partition_info_v1_1 40 part_info[SPMD_LP_MAX_SUPPORTED_SP] = { 0 }; 41 42 uint16_t num_partitions = 0; 43 44 if (!spmd_el3_invoke_partition_info_get(target_uuid, 0, 0, &ret)) { 45 panic(); 46 } 47 48 if (is_ffa_error(&ret)) { 49 panic(); 50 } 51 52 num_partitions = ffa_partition_info_regs_get_last_idx(&ret) + 1; 53 if (num_partitions > SPMD_LP_MAX_SUPPORTED_SP) { 54 panic(); 55 } 56 57 INFO("Number of secure partitions = %d\n", num_partitions); 58 59 for (uint16_t i = 0; i < num_partitions; i++) { 60 INFO("***Start Partition***\n"); 61 if (!ffa_partition_info_regs_get_part_info(&ret, i, &part_info[i])) 62 panic(); 63 INFO("\tPartition ID: 0x%x\n", part_info[i].ep_id); 64 INFO("\tvCPU count:0x%x\n", part_info[i].execution_ctx_count); 65 INFO("\tProperties: 0x%x\n", part_info[i].properties); 66 INFO("\tUUID: 0x%x 0x%x 0x%x 0x%x\n", part_info[i].uuid[0], 67 part_info[i].uuid[1], part_info[i].uuid[2], 68 part_info[i].uuid[3]); 69 INFO("***End Partition***\n"); 70 } 71 72 } 73 74 static int32_t fvp_spmd_logical_partition_init(void) 75 { 76 INFO("FVP SPMD LSP: Init function called.\n"); 77 78 fvp_get_partition_info(); 79 return 0; 80 } 81 82 /* 83 * Platform specific SMC handler used to translate SIP SMCs or other platform 84 * specific SMCs into FF-A direct messages. 85 */ 86 uintptr_t plat_spmd_logical_sp_smc_handler(unsigned int smc_fid, 87 u_register_t x1, 88 u_register_t x2, 89 u_register_t x3, 90 u_register_t x4, 91 void *cookie, 92 void *handle, 93 u_register_t flags) 94 { 95 struct ffa_value retval = { 0 }; 96 uint64_t send_recv_id = SPMD_LP_PARTITION_ID << 16 | 0x8001; 97 98 /* 99 * Forward the SMC as direct request. 100 */ 101 if (!spmd_el3_ffa_msg_direct_req(send_recv_id, x2, x3, x4, handle, &retval)) { 102 panic(); 103 } 104 105 SMC_RET8(handle, retval.func, retval.arg1, retval.arg2, retval.arg3, 106 retval.arg4, retval.arg5, retval.arg6, retval.arg7); 107 } 108 109 /* Register SPMD logical partition */ 110 DECLARE_SPMD_LOGICAL_PARTITION( 111 fvp_spmd_logical_partition, 112 fvp_spmd_logical_partition_init,/* Init Function */ 113 SPMD_LP_PARTITION_ID, /* FF-A Partition ID */ 114 SPMD_LP_UUID, /* UUID */ 115 SPMD_PARTITION_PROPERTIES /* Partition Properties. */ 116 ); 117