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