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