1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2022, Arm Limited. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #ifndef FFA_HELPERS_H 8*91f16700Schasinglulu #define FFA_HELPERS_H 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <stdint.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #include "../../services/std_svc/spm/el3_spmc/spmc.h" 13*91f16700Schasinglulu #include "../../services/std_svc/spm/el3_spmc/spmc_shared_mem.h" 14*91f16700Schasinglulu #include <services/el3_spmc_ffa_memory.h> 15*91f16700Schasinglulu #include <services/ffa_svc.h> 16*91f16700Schasinglulu #include "tsp_private.h" 17*91f16700Schasinglulu 18*91f16700Schasinglulu static inline uint32_t ffa_func_id(smc_args_t val) 19*91f16700Schasinglulu { 20*91f16700Schasinglulu return (uint32_t) val._regs[0]; 21*91f16700Schasinglulu } 22*91f16700Schasinglulu 23*91f16700Schasinglulu static inline int32_t ffa_error_code(smc_args_t val) 24*91f16700Schasinglulu { 25*91f16700Schasinglulu return (uint32_t) val._regs[2]; 26*91f16700Schasinglulu } 27*91f16700Schasinglulu 28*91f16700Schasinglulu extern uint8_t mem_region_buffer[4096 * 2] __aligned(PAGE_SIZE); 29*91f16700Schasinglulu #define REGION_BUF_SIZE sizeof(mem_region_buffer) 30*91f16700Schasinglulu 31*91f16700Schasinglulu /** The maximum number of recipients a memory region may be sent to. */ 32*91f16700Schasinglulu #define MAX_MEM_SHARE_RECIPIENTS 2U 33*91f16700Schasinglulu 34*91f16700Schasinglulu /* FFA Memory Management mode flags. */ 35*91f16700Schasinglulu #define FFA_FLAG_SHARE_MEMORY (1U << 3) 36*91f16700Schasinglulu #define FFA_FLAG_LEND_MEMORY (1U << 4) 37*91f16700Schasinglulu 38*91f16700Schasinglulu #define FFA_FLAG_MEMORY_MASK (3U << 3) 39*91f16700Schasinglulu 40*91f16700Schasinglulu #define FFA_MEM_HANDLE_LOW(x) (x & 0xFFFFFFFF) 41*91f16700Schasinglulu #define FFA_MEM_HANDLE_HIGH(x) (x >> 32) 42*91f16700Schasinglulu 43*91f16700Schasinglulu #define FFA_MEM_PERM_DATA_OFFSET 0 44*91f16700Schasinglulu #define FFA_MEM_PERM_DATA_MASK 0x3 45*91f16700Schasinglulu 46*91f16700Schasinglulu static inline uint32_t ffa_mem_relinquish_init( 47*91f16700Schasinglulu struct ffa_mem_relinquish_descriptor *relinquish_request, 48*91f16700Schasinglulu uint64_t handle, ffa_mtd_flag32_t flags, 49*91f16700Schasinglulu ffa_endpoint_id16_t sender) 50*91f16700Schasinglulu { 51*91f16700Schasinglulu relinquish_request->handle = handle; 52*91f16700Schasinglulu relinquish_request->flags = flags; 53*91f16700Schasinglulu relinquish_request->endpoint_count = 1; 54*91f16700Schasinglulu relinquish_request->endpoint_array[0] = sender; 55*91f16700Schasinglulu 56*91f16700Schasinglulu return sizeof(struct ffa_mem_relinquish_descriptor) + sizeof(ffa_endpoint_id16_t); 57*91f16700Schasinglulu } 58*91f16700Schasinglulu 59*91f16700Schasinglulu /** 60*91f16700Schasinglulu * Gets the `ffa_comp_mrd` for the given receiver from an 61*91f16700Schasinglulu * `ffa_mtd`, or NULL if it is not valid. 62*91f16700Schasinglulu */ 63*91f16700Schasinglulu static inline struct ffa_comp_mrd * 64*91f16700Schasinglulu ffa_memory_region_get_composite(struct ffa_mtd *memory_region, 65*91f16700Schasinglulu uint32_t receiver_index) 66*91f16700Schasinglulu { 67*91f16700Schasinglulu struct ffa_emad_v1_0 *receivers; 68*91f16700Schasinglulu uint32_t offset; 69*91f16700Schasinglulu 70*91f16700Schasinglulu receivers = (struct ffa_emad_v1_0 *) 71*91f16700Schasinglulu ((uint8_t *) memory_region + 72*91f16700Schasinglulu memory_region->emad_offset + 73*91f16700Schasinglulu (memory_region->emad_size * receiver_index)); 74*91f16700Schasinglulu offset = receivers->comp_mrd_offset; 75*91f16700Schasinglulu 76*91f16700Schasinglulu if (offset == 0U) { 77*91f16700Schasinglulu return NULL; 78*91f16700Schasinglulu } 79*91f16700Schasinglulu 80*91f16700Schasinglulu return (struct ffa_comp_mrd *) 81*91f16700Schasinglulu ((uint8_t *) memory_region + offset); 82*91f16700Schasinglulu } 83*91f16700Schasinglulu 84*91f16700Schasinglulu static inline uint32_t ffa_get_data_access_attr(ffa_mem_perm8_t perm) 85*91f16700Schasinglulu { 86*91f16700Schasinglulu return ((perm >> FFA_MEM_PERM_DATA_OFFSET) & FFA_MEM_PERM_DATA_MASK); 87*91f16700Schasinglulu } 88*91f16700Schasinglulu 89*91f16700Schasinglulu smc_args_t ffa_mem_frag_rx(uint64_t handle, uint32_t recv_length); 90*91f16700Schasinglulu bool ffa_mem_relinquish(void); 91*91f16700Schasinglulu bool ffa_rx_release(void); 92*91f16700Schasinglulu bool memory_relinquish(struct ffa_mem_relinquish_descriptor *m, uint64_t handle, 93*91f16700Schasinglulu ffa_endpoint_id16_t id); 94*91f16700Schasinglulu bool ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages); 95*91f16700Schasinglulu bool memory_retrieve(struct mailbox *mb, 96*91f16700Schasinglulu struct ffa_mtd **retrieved, 97*91f16700Schasinglulu uint64_t handle, ffa_endpoint_id16_t sender, 98*91f16700Schasinglulu ffa_endpoint_id16_t *receivers, uint32_t receiver_count, 99*91f16700Schasinglulu ffa_mtd_flag32_t flags, uint32_t *frag_length, 100*91f16700Schasinglulu uint32_t *total_length); 101*91f16700Schasinglulu 102*91f16700Schasinglulu smc_args_t ffa_msg_send_direct_req(ffa_endpoint_id16_t sender, 103*91f16700Schasinglulu ffa_endpoint_id16_t receiver, 104*91f16700Schasinglulu uint32_t arg3, 105*91f16700Schasinglulu uint32_t arg4, 106*91f16700Schasinglulu uint32_t arg5, 107*91f16700Schasinglulu uint32_t arg6, 108*91f16700Schasinglulu uint32_t arg7); 109*91f16700Schasinglulu smc_args_t *ffa_msg_send_direct_resp(ffa_endpoint_id16_t sender, 110*91f16700Schasinglulu ffa_endpoint_id16_t receiver, 111*91f16700Schasinglulu uint32_t arg3, 112*91f16700Schasinglulu uint32_t arg4, 113*91f16700Schasinglulu uint32_t arg5, 114*91f16700Schasinglulu uint32_t arg6, 115*91f16700Schasinglulu uint32_t arg7); 116*91f16700Schasinglulu #endif /* FFA_HELPERS_H */ 117