xref: /rk3399_ARM-atf/include/services/el3_spmd_logical_sp.h (revision f5cb144df1d96c9adf45fbf2376b4068d16d8701)
1 /*
2  * Copyright (c) 2023-2026, Arm Limited and Contributors. All rights reserved.
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #ifndef EL3_SPMD_LOGICAL_SP_H
6 #define EL3_SPMD_LOGICAL_SP_H
7 
8 #include <common/bl_common.h>
9 #include <lib/cassert.h>
10 #include <services/ffa_svc.h>
11 
12 /*******************************************************************************
13  * Structure definition, typedefs & constants for the SPMD Logical Partitions.
14  ******************************************************************************/
15 /* Prototype for SPMD logical partition initializing function. */
16 typedef int32_t (*ffa_spmd_lp_init_t)(void);
17 
18 /* SPMD Logical Partition Descriptor. */
19 struct spmd_lp_desc {
20 	ffa_spmd_lp_init_t init;
21 	uint16_t sp_id;
22 	uint32_t properties;
23 	uint32_t uuid[4];  /* Little Endian. */
24 	const char *debug_name;
25 };
26 
27 struct ffa_value {
28 	uint64_t func;
29 	uint64_t arg1;
30 	uint64_t arg2;
31 	uint64_t arg3;
32 	uint64_t arg4;
33 	uint64_t arg5;
34 	uint64_t arg6;
35 	uint64_t arg7;
36 	uint64_t arg8;
37 	uint64_t arg9;
38 	uint64_t arg10;
39 	uint64_t arg11;
40 	uint64_t arg12;
41 	uint64_t arg13;
42 	uint64_t arg14;
43 	uint64_t arg15;
44 	uint64_t arg16;
45 	uint64_t arg17;
46 };
47 
48 /* Convenience macro to declare a SPMD logical partition descriptor. */
49 #define DECLARE_SPMD_LOGICAL_PARTITION(_name, _init, _sp_id, _uuid, _properties) \
50 	static const struct spmd_lp_desc __partition_desc_ ## _name	    \
51 		__section(".spmd_lp_descs") __used = {			    \
52 			.debug_name = #_name,				    \
53 			.init = (_init),				    \
54 			.sp_id = (_sp_id),				    \
55 			.uuid = _uuid,					    \
56 			.properties = (_properties),			    \
57 		}
58 
59 IMPORT_SYM(uintptr_t, __SPMD_LP_DESCS_START__,	SPMD_LP_DESCS_START);
60 IMPORT_SYM(uintptr_t, __SPMD_LP_DESCS_END__,	SPMD_LP_DESCS_END);
61 
62 #define SPMD_LP_DESCS_COUNT ((SPMD_LP_DESCS_END - SPMD_LP_DESCS_START) \
63 			  / sizeof(struct spmd_lp_desc))
64 CASSERT(sizeof(struct spmd_lp_desc) == 40, assert_spmd_lp_desc_size_mismatch);
65 
66 /*
67  * Reserve 63 IDs for SPMD Logical Partitions. Currently, 0xFFC0 to 0xFFFE
68  * is reserved.
69  */
70 #define SPMD_LP_ID_END		(SPMD_DIRECT_MSG_ENDPOINT_ID - 1)
71 #define SPMD_LP_ID_START	(SPMD_LP_ID_END - 62)
72 
73 /*
74  * TODO: Arbitrary number. Can make this platform specific in the future,
75  * no known use cases for more LPs at this point.
76  */
77 #define EL3_SPMD_MAX_NUM_LP	U(5)
78 
79 /*
80  * Maximum number of struct ffa_partition_info_v1_3 descriptors that fit in one
81  * FFA_PARTITION_INFO_GET_REGS_64 response. The ABI lets the callee populate
82  * args3-args17 (15 x 64-bit registers = 120 bytes) in struct ffa_value; each
83  * descriptor consumes sizeof(struct ffa_partition_info_v1_3) = 48 bytes.
84  * Therefore, rounding it means 2 entries per call for FF-A v1.3.
85  */
86 #define MAX_INFO_REGS_ENTRIES_PER_CALL	2U
87 
88 CASSERT(sizeof(struct ffa_partition_info_v1_3) == 48,
89 	ffa_partition_info_desc_size_mismatch);
90 
91 static inline bool is_spmd_lp_id(unsigned int id)
92 {
93 #if ENABLE_SPMD_LP
94 	return (id >= SPMD_LP_ID_START && id <= SPMD_LP_ID_END);
95 #else
96 	return false;
97 #endif
98 }
99 
100 static inline bool is_ffa_error(struct ffa_value *retval)
101 {
102 	return retval->func == FFA_ERROR;
103 }
104 
105 static inline bool is_ffa_success(struct ffa_value *retval)
106 {
107 	return (retval->func == FFA_SUCCESS_SMC32) ||
108 		(retval->func == FFA_SUCCESS_SMC64);
109 }
110 
111 static inline bool is_ffa_direct_msg_resp(struct ffa_value *retval)
112 {
113 	return (retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC32) ||
114 		(retval->func == FFA_MSG_SEND_DIRECT_RESP2_SMC64) ||
115 		(retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC64);
116 }
117 
118 static inline uint16_t ffa_partition_info_regs_get_last_idx(
119 	struct ffa_value *args)
120 {
121 	return (uint16_t)(args->arg2 & 0xFFFFU);
122 }
123 
124 static inline uint16_t ffa_partition_info_regs_get_curr_idx(
125 	struct ffa_value *args)
126 {
127 	return (uint16_t)((args->arg2 >> 16) & 0xFFFFU);
128 }
129 
130 static inline uint16_t ffa_partition_info_regs_get_tag(struct ffa_value *args)
131 {
132 	return (uint16_t)((args->arg2 >> 32) & 0xFFFFU);
133 }
134 
135 static inline uint16_t ffa_partition_info_regs_get_desc_size(
136 	struct ffa_value *args)
137 {
138 	return (uint16_t)(args->arg2 >> 48);
139 }
140 
141 uint64_t spmd_el3_populate_logical_partition_info(void *handle, uint64_t x1,
142 						  uint64_t x2, uint64_t x3);
143 
144 bool ffa_partition_info_regs_get_part_info(
145 	struct ffa_value *args, uint8_t idx,
146 	struct ffa_partition_info_v1_3 *partition_info);
147 
148 bool spmd_el3_invoke_partition_info_get(
149 				const uint32_t target_uuid[4],
150 				const uint16_t start_index,
151 				const uint16_t tag,
152 				struct ffa_value *retval);
153 void spmd_logical_sp_set_spmc_initialized(void);
154 void spmc_logical_sp_set_spmc_failure(void);
155 
156 int32_t spmd_logical_sp_init(void);
157 bool spmd_el3_ffa_msg_direct_req(uint64_t x1,
158 				 uint64_t x2,
159 				 uint64_t x3,
160 				 uint64_t x4,
161 				 void *handle,
162 				 struct ffa_value *retval);
163 
164 bool spmd_el3_ffa_msg_direct_req2(uint64_t x1,
165 				 uint64_t x2,
166 				 uint64_t x3,
167 				 uint64_t x4,
168 				 void *handle,
169 				 struct ffa_value *retval);
170 
171 uintptr_t plat_spmd_logical_sp_smc_handler(unsigned int smc_fid,
172 		u_register_t x1,
173 		u_register_t x2,
174 		u_register_t x3,
175 		u_register_t x4,
176 		void *cookie,
177 		void *handle,
178 		u_register_t flags);
179 
180 #endif /* EL3_SPMD_LOGICAL_SP_H */
181