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