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