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 /* 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 static inline bool is_spmd_lp_id(unsigned int id) 80 { 81 #if ENABLE_SPMD_LP 82 return (id >= SPMD_LP_ID_START && id <= SPMD_LP_ID_END); 83 #else 84 return false; 85 #endif 86 } 87 88 static inline bool is_ffa_error(struct ffa_value *retval) 89 { 90 return retval->func == FFA_ERROR; 91 } 92 93 static inline bool is_ffa_success(struct ffa_value *retval) 94 { 95 return (retval->func == FFA_SUCCESS_SMC32) || 96 (retval->func == FFA_SUCCESS_SMC64); 97 } 98 99 static inline bool is_ffa_direct_msg_resp(struct ffa_value *retval) 100 { 101 return (retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC32) || 102 (retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC64); 103 } 104 105 static inline uint16_t ffa_partition_info_regs_get_last_idx( 106 struct ffa_value *args) 107 { 108 return (uint16_t)(args->arg2 & 0xFFFFU); 109 } 110 111 static inline uint16_t ffa_partition_info_regs_get_curr_idx( 112 struct ffa_value *args) 113 { 114 return (uint16_t)((args->arg2 >> 16) & 0xFFFFU); 115 } 116 117 static inline uint16_t ffa_partition_info_regs_get_tag(struct ffa_value *args) 118 { 119 return (uint16_t)((args->arg2 >> 32) & 0xFFFFU); 120 } 121 122 static inline uint16_t ffa_partition_info_regs_get_desc_size( 123 struct ffa_value *args) 124 { 125 return (uint16_t)(args->arg2 >> 48); 126 } 127 128 uint64_t spmd_el3_populate_logical_partition_info(void *handle, uint64_t x1, 129 uint64_t x2, uint64_t x3); 130 131 bool ffa_partition_info_regs_get_part_info( 132 struct ffa_value *args, uint8_t idx, 133 struct ffa_partition_info_v1_1 *partition_info); 134 135 bool spmd_el3_invoke_partition_info_get( 136 const uint32_t target_uuid[4], 137 const uint16_t start_index, 138 const uint16_t tag, 139 struct ffa_value *retval); 140 void spmd_logical_sp_set_spmc_initialized(void); 141 void spmc_logical_sp_set_spmc_failure(void); 142 143 int32_t spmd_logical_sp_init(void); 144 bool spmd_el3_ffa_msg_direct_req(uint64_t x1, 145 uint64_t x2, 146 uint64_t x3, 147 uint64_t x4, 148 void *handle, 149 struct ffa_value *retval); 150 151 uintptr_t plat_spmd_logical_sp_smc_handler(unsigned int smc_fid, 152 u_register_t x1, 153 u_register_t x2, 154 u_register_t x3, 155 u_register_t x4, 156 void *cookie, 157 void *handle, 158 u_register_t flags); 159 160 #endif /* EL3_SPMD_LOGICAL_SP_H */ 161