1 /*
2  * Copyright (c) 2023, 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
fvp_get_partition_info(void)18 static void fvp_get_partition_info(void)
19 {
20 	struct ffa_value ret = { 0 };
21 	uint32_t target_uuid[4] = { 0 };
22 	static struct ffa_partition_info_v1_1
23 		part_info[SPMD_LP_MAX_SUPPORTED_SP] = { 0 };
24 
25 	uint16_t num_partitions = 0;
26 
27 	if (!spmd_el3_invoke_partition_info_get(target_uuid, 0, 0, &ret)) {
28 		panic();
29 	}
30 
31 	if (is_ffa_error(&ret)) {
32 		panic();
33 	}
34 
35 	num_partitions = ffa_partition_info_regs_get_last_idx(&ret) + 1;
36 	if (num_partitions > SPMD_LP_MAX_SUPPORTED_SP) {
37 		panic();
38 	}
39 
40 	INFO("Number of secure partitions = %d\n", num_partitions);
41 
42 	for (uint16_t i = 0; i < num_partitions; i++) {
43 		INFO("***Start Partition***\n");
44 		if (!ffa_partition_info_regs_get_part_info(&ret, i, &part_info[i]))
45 			panic();
46 		INFO("\tPartition ID: 0x%x\n", part_info[i].ep_id);
47 		INFO("\tvCPU count:0x%x\n", part_info[i].execution_ctx_count);
48 		INFO("\tProperties: 0x%x\n", part_info[i].properties);
49 		INFO("\tUUID: 0x%x 0x%x 0x%x 0x%x\n", part_info[i].uuid[0],
50 				part_info[i].uuid[1], part_info[i].uuid[2],
51 				part_info[i].uuid[3]);
52 		INFO("***End Partition***\n");
53 	}
54 
55 }
56 
fvp_spmd_logical_partition_init(void)57 static int32_t fvp_spmd_logical_partition_init(void)
58 {
59 	INFO("FVP SPMD LSP: Init function called.\n");
60 
61 	fvp_get_partition_info();
62 	return 0;
63 }
64 
65 /*
66  * Platform specific SMC handler used to translate SIP SMCs or other platform
67  * specific SMCs into FF-A direct messages.
68  */
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)69 uintptr_t plat_spmd_logical_sp_smc_handler(unsigned int smc_fid,
70 			u_register_t x1,
71 			u_register_t x2,
72 			u_register_t x3,
73 			u_register_t x4,
74 			void *cookie,
75 			void *handle,
76 			u_register_t flags)
77 {
78 	struct ffa_value retval = { 0 };
79 	uint64_t send_recv_id = SPMD_LP_PARTITION_ID << 16 | 0x8001;
80 
81 	/*
82 	 * Forward the SMC as direct request.
83 	 */
84 	if (!spmd_el3_ffa_msg_direct_req(send_recv_id, x2, x3, x4, handle, &retval)) {
85 		panic();
86 	}
87 
88 	SMC_RET8(handle, retval.func, retval.arg1, retval.arg2, retval.arg3,
89 			retval.arg4, retval.arg5, retval.arg6, retval.arg7);
90 }
91 
92 /* Register SPMD logical partition  */
93 DECLARE_SPMD_LOGICAL_PARTITION(
94 	fvp_spmd_logical_partition,
95 	fvp_spmd_logical_partition_init,/* Init Function */
96 	SPMD_LP_PARTITION_ID,		/* FF-A Partition ID */
97 	SPMD_LP_UUID,			/* UUID */
98 	SPMD_PARTITION_PROPERTIES	/* Partition Properties. */
99 );
100