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
fvp_get_partition_info(void)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
fvp_spmd_logical_partition_init(void)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 */
plat_spmd_logical_sp_smc_handler(unsigned int smc_fid,u_register_t x1,u_register_t x2,u_register_t x3,u_register_t x4,void * cookie,void * handle,u_register_t flags)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