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