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