1890b5088SRaghu Krishnamurthy /* 2890b5088SRaghu Krishnamurthy * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved. 3890b5088SRaghu Krishnamurthy * SPDX-License-Identifier: BSD-3-Clause 4890b5088SRaghu Krishnamurthy */ 5890b5088SRaghu Krishnamurthy #ifndef EL3_SPMD_LOGICAL_SP_H 6890b5088SRaghu Krishnamurthy #define EL3_SPMD_LOGICAL_SP_H 7890b5088SRaghu Krishnamurthy 8890b5088SRaghu Krishnamurthy #include <common/bl_common.h> 9890b5088SRaghu Krishnamurthy #include <lib/cassert.h> 10890b5088SRaghu Krishnamurthy #include <services/ffa_svc.h> 11890b5088SRaghu Krishnamurthy 12890b5088SRaghu Krishnamurthy /******************************************************************************* 13890b5088SRaghu Krishnamurthy * Structure definition, typedefs & constants for the SPMD Logical Partitions. 14890b5088SRaghu Krishnamurthy ******************************************************************************/ 1566bdfd6eSRaghu Krishnamurthy typedef struct spmd_spm_core_context spmd_spm_core_context_t; 16890b5088SRaghu Krishnamurthy 17890b5088SRaghu Krishnamurthy /* Prototype for SPMD logical partition initializing function. */ 18890b5088SRaghu Krishnamurthy typedef int32_t (*ffa_spmd_lp_init_t)(void); 19890b5088SRaghu Krishnamurthy 20890b5088SRaghu Krishnamurthy /* SPMD Logical Partition Descriptor. */ 21890b5088SRaghu Krishnamurthy struct spmd_lp_desc { 22890b5088SRaghu Krishnamurthy ffa_spmd_lp_init_t init; 23890b5088SRaghu Krishnamurthy uint16_t sp_id; 24890b5088SRaghu Krishnamurthy uint32_t properties; 25890b5088SRaghu Krishnamurthy uint32_t uuid[4]; /* Little Endian. */ 26890b5088SRaghu Krishnamurthy const char *debug_name; 27890b5088SRaghu Krishnamurthy }; 28890b5088SRaghu Krishnamurthy 2966bdfd6eSRaghu Krishnamurthy struct ffa_value { 3066bdfd6eSRaghu Krishnamurthy uint64_t func; 3166bdfd6eSRaghu Krishnamurthy uint64_t arg1; 3266bdfd6eSRaghu Krishnamurthy uint64_t arg2; 3366bdfd6eSRaghu Krishnamurthy uint64_t arg3; 3466bdfd6eSRaghu Krishnamurthy uint64_t arg4; 3566bdfd6eSRaghu Krishnamurthy uint64_t arg5; 3666bdfd6eSRaghu Krishnamurthy uint64_t arg6; 3766bdfd6eSRaghu Krishnamurthy uint64_t arg7; 380b850e9eSRaghu Krishnamurthy uint64_t arg8; 390b850e9eSRaghu Krishnamurthy uint64_t arg9; 400b850e9eSRaghu Krishnamurthy uint64_t arg10; 410b850e9eSRaghu Krishnamurthy uint64_t arg11; 420b850e9eSRaghu Krishnamurthy uint64_t arg12; 430b850e9eSRaghu Krishnamurthy uint64_t arg13; 440b850e9eSRaghu Krishnamurthy uint64_t arg14; 450b850e9eSRaghu Krishnamurthy uint64_t arg15; 460b850e9eSRaghu Krishnamurthy uint64_t arg16; 470b850e9eSRaghu Krishnamurthy uint64_t arg17; 4866bdfd6eSRaghu Krishnamurthy }; 4966bdfd6eSRaghu Krishnamurthy 50890b5088SRaghu Krishnamurthy /* Convenience macro to declare a SPMD logical partition descriptor. */ 51890b5088SRaghu Krishnamurthy #define DECLARE_SPMD_LOGICAL_PARTITION(_name, _init, _sp_id, _uuid, _properties) \ 52890b5088SRaghu Krishnamurthy static const struct spmd_lp_desc __partition_desc_ ## _name \ 53890b5088SRaghu Krishnamurthy __section(".spmd_lp_descs") __used = { \ 54890b5088SRaghu Krishnamurthy .debug_name = #_name, \ 55890b5088SRaghu Krishnamurthy .init = (_init), \ 56890b5088SRaghu Krishnamurthy .sp_id = (_sp_id), \ 57890b5088SRaghu Krishnamurthy .uuid = _uuid, \ 58890b5088SRaghu Krishnamurthy .properties = (_properties), \ 59890b5088SRaghu Krishnamurthy } 60890b5088SRaghu Krishnamurthy 61890b5088SRaghu Krishnamurthy IMPORT_SYM(uintptr_t, __SPMD_LP_DESCS_START__, SPMD_LP_DESCS_START); 62890b5088SRaghu Krishnamurthy IMPORT_SYM(uintptr_t, __SPMD_LP_DESCS_END__, SPMD_LP_DESCS_END); 63890b5088SRaghu Krishnamurthy 64890b5088SRaghu Krishnamurthy #define SPMD_LP_DESCS_COUNT ((SPMD_LP_DESCS_END - SPMD_LP_DESCS_START) \ 65890b5088SRaghu Krishnamurthy / sizeof(struct spmd_lp_desc)) 66890b5088SRaghu Krishnamurthy CASSERT(sizeof(struct spmd_lp_desc) == 40, assert_spmd_lp_desc_size_mismatch); 67890b5088SRaghu Krishnamurthy 68890b5088SRaghu Krishnamurthy /* 69890b5088SRaghu Krishnamurthy * Reserve 63 IDs for SPMD Logical Partitions. Currently, 0xFFC0 to 0xFFFE 70890b5088SRaghu Krishnamurthy * is reserved. 71890b5088SRaghu Krishnamurthy */ 72890b5088SRaghu Krishnamurthy #define SPMD_LP_ID_END (SPMD_DIRECT_MSG_ENDPOINT_ID - 1) 73890b5088SRaghu Krishnamurthy #define SPMD_LP_ID_START (SPMD_LP_ID_END - 62) 74890b5088SRaghu Krishnamurthy 7595f7f6d8SRaghu Krishnamurthy /* 7695f7f6d8SRaghu Krishnamurthy * TODO: Arbitrary number. Can make this platform specific in the future, 7795f7f6d8SRaghu Krishnamurthy * no known use cases for more LPs at this point. 7895f7f6d8SRaghu Krishnamurthy */ 7995f7f6d8SRaghu Krishnamurthy #define EL3_SPMD_MAX_NUM_LP U(5) 8095f7f6d8SRaghu Krishnamurthy 81890b5088SRaghu Krishnamurthy static inline bool is_spmd_lp_id(unsigned int id) 82890b5088SRaghu Krishnamurthy { 8366bdfd6eSRaghu Krishnamurthy #if ENABLE_SPMD_LP 84890b5088SRaghu Krishnamurthy return (id >= SPMD_LP_ID_START && id <= SPMD_LP_ID_END); 8566bdfd6eSRaghu Krishnamurthy #else 8666bdfd6eSRaghu Krishnamurthy return false; 8766bdfd6eSRaghu Krishnamurthy #endif 8866bdfd6eSRaghu Krishnamurthy } 8966bdfd6eSRaghu Krishnamurthy 9066bdfd6eSRaghu Krishnamurthy static inline bool is_ffa_error(struct ffa_value *retval) 9166bdfd6eSRaghu Krishnamurthy { 9266bdfd6eSRaghu Krishnamurthy return retval->func == FFA_ERROR; 9366bdfd6eSRaghu Krishnamurthy } 9466bdfd6eSRaghu Krishnamurthy 950b850e9eSRaghu Krishnamurthy static inline bool is_ffa_success(struct ffa_value *retval) 960b850e9eSRaghu Krishnamurthy { 970b850e9eSRaghu Krishnamurthy return (retval->func == FFA_SUCCESS_SMC32) || 980b850e9eSRaghu Krishnamurthy (retval->func == FFA_SUCCESS_SMC64); 990b850e9eSRaghu Krishnamurthy } 1000b850e9eSRaghu Krishnamurthy 10166bdfd6eSRaghu Krishnamurthy static inline bool is_ffa_direct_msg_resp(struct ffa_value *retval) 10266bdfd6eSRaghu Krishnamurthy { 10366bdfd6eSRaghu Krishnamurthy return (retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC32) || 10466bdfd6eSRaghu Krishnamurthy (retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC64); 105890b5088SRaghu Krishnamurthy } 106890b5088SRaghu Krishnamurthy 1070b850e9eSRaghu Krishnamurthy static inline uint16_t ffa_partition_info_regs_get_last_idx( 108*b04343f3SRaghu Krishnamurthy struct ffa_value *args) 1090b850e9eSRaghu Krishnamurthy { 110*b04343f3SRaghu Krishnamurthy return (uint16_t)(args->arg2 & 0xFFFFU); 1110b850e9eSRaghu Krishnamurthy } 1120b850e9eSRaghu Krishnamurthy 1130b850e9eSRaghu Krishnamurthy static inline uint16_t ffa_partition_info_regs_get_curr_idx( 114*b04343f3SRaghu Krishnamurthy struct ffa_value *args) 1150b850e9eSRaghu Krishnamurthy { 116*b04343f3SRaghu Krishnamurthy return (uint16_t)((args->arg2 >> 16) & 0xFFFFU); 1170b850e9eSRaghu Krishnamurthy } 1180b850e9eSRaghu Krishnamurthy 119*b04343f3SRaghu Krishnamurthy static inline uint16_t ffa_partition_info_regs_get_tag(struct ffa_value *args) 1200b850e9eSRaghu Krishnamurthy { 121*b04343f3SRaghu Krishnamurthy return (uint16_t)((args->arg2 >> 32) & 0xFFFFU); 1220b850e9eSRaghu Krishnamurthy } 1230b850e9eSRaghu Krishnamurthy 1240b850e9eSRaghu Krishnamurthy static inline uint16_t ffa_partition_info_regs_get_desc_size( 125*b04343f3SRaghu Krishnamurthy struct ffa_value *args) 1260b850e9eSRaghu Krishnamurthy { 127*b04343f3SRaghu Krishnamurthy return (uint16_t)(args->arg2 >> 48); 1280b850e9eSRaghu Krishnamurthy } 1290b850e9eSRaghu Krishnamurthy 13095f7f6d8SRaghu Krishnamurthy uint64_t spmd_el3_populate_logical_partition_info(void *handle, uint64_t x1, 13195f7f6d8SRaghu Krishnamurthy uint64_t x2, uint64_t x3); 13295f7f6d8SRaghu Krishnamurthy 1330b850e9eSRaghu Krishnamurthy bool ffa_partition_info_regs_get_part_info( 134*b04343f3SRaghu Krishnamurthy struct ffa_value *args, uint8_t idx, 1350b850e9eSRaghu Krishnamurthy struct ffa_partition_info_v1_1 *partition_info); 1360b850e9eSRaghu Krishnamurthy 1370b850e9eSRaghu Krishnamurthy bool spmd_el3_invoke_partition_info_get( 1380b850e9eSRaghu Krishnamurthy const uint32_t target_uuid[4], 1390b850e9eSRaghu Krishnamurthy const uint16_t start_index, 1400b850e9eSRaghu Krishnamurthy const uint16_t tag, 1410b850e9eSRaghu Krishnamurthy struct ffa_value *retval); 142890b5088SRaghu Krishnamurthy void spmd_logical_sp_set_spmc_initialized(void); 143890b5088SRaghu Krishnamurthy void spmc_logical_sp_set_spmc_failure(void); 144890b5088SRaghu Krishnamurthy 145890b5088SRaghu Krishnamurthy int32_t spmd_logical_sp_init(void); 14666bdfd6eSRaghu Krishnamurthy bool is_spmd_logical_sp_dir_req_in_progress( 14766bdfd6eSRaghu Krishnamurthy spmd_spm_core_context_t *ctx); 14866bdfd6eSRaghu Krishnamurthy 1490b850e9eSRaghu Krishnamurthy bool is_spmd_logical_sp_info_regs_req_in_progress( 1500b850e9eSRaghu Krishnamurthy spmd_spm_core_context_t *ctx); 1510b850e9eSRaghu Krishnamurthy 15266bdfd6eSRaghu Krishnamurthy bool spmd_el3_ffa_msg_direct_req(uint64_t x1, 15366bdfd6eSRaghu Krishnamurthy uint64_t x2, 15466bdfd6eSRaghu Krishnamurthy uint64_t x3, 15566bdfd6eSRaghu Krishnamurthy uint64_t x4, 15666bdfd6eSRaghu Krishnamurthy void *handle, 15766bdfd6eSRaghu Krishnamurthy struct ffa_value *retval); 158890b5088SRaghu Krishnamurthy 159a1a9a950SRaghu Krishnamurthy uintptr_t plat_spmd_logical_sp_smc_handler(unsigned int smc_fid, 160a1a9a950SRaghu Krishnamurthy u_register_t x1, 161a1a9a950SRaghu Krishnamurthy u_register_t x2, 162a1a9a950SRaghu Krishnamurthy u_register_t x3, 163a1a9a950SRaghu Krishnamurthy u_register_t x4, 164a1a9a950SRaghu Krishnamurthy void *cookie, 165a1a9a950SRaghu Krishnamurthy void *handle, 166a1a9a950SRaghu Krishnamurthy u_register_t flags); 167a1a9a950SRaghu Krishnamurthy 168890b5088SRaghu Krishnamurthy #endif /* EL3_SPMD_LOGICAL_SP_H */ 169