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 extern uint8_t mem_region_buffer[4096 * 2] __aligned(PAGE_SIZE); 29 #define REGION_BUF_SIZE sizeof(mem_region_buffer) 30 31 /** The maximum number of recipients a memory region may be sent to. */ 32 #define MAX_MEM_SHARE_RECIPIENTS 2U 33 34 /* FFA Memory Management mode flags. */ 35 #define FFA_FLAG_SHARE_MEMORY (1U << 3) 36 #define FFA_FLAG_LEND_MEMORY (1U << 4) 37 38 #define FFA_FLAG_MEMORY_MASK (3U << 3) 39 40 #define FFA_MEM_HANDLE_LOW(x) (x & 0xFFFFFFFF) 41 #define FFA_MEM_HANDLE_HIGH(x) (x >> 32) 42 43 #define FFA_MEM_PERM_DATA_OFFSET 0 44 #define FFA_MEM_PERM_DATA_MASK 0x3 45 46 static inline uint32_t ffa_mem_relinquish_init( 47 struct ffa_mem_relinquish_descriptor *relinquish_request, 48 uint64_t handle, ffa_mtd_flag32_t flags, 49 ffa_endpoint_id16_t sender) 50 { 51 relinquish_request->handle = handle; 52 relinquish_request->flags = flags; 53 relinquish_request->endpoint_count = 1; 54 relinquish_request->endpoint_array[0] = sender; 55 56 return sizeof(struct ffa_mem_relinquish_descriptor) + sizeof(ffa_endpoint_id16_t); 57 } 58 59 /** 60 * Gets the `ffa_comp_mrd` for the given receiver from an 61 * `ffa_mtd`, or NULL if it is not valid. 62 */ 63 static inline struct ffa_comp_mrd * 64 ffa_memory_region_get_composite(struct ffa_mtd *memory_region, 65 uint32_t receiver_index) 66 { 67 struct ffa_emad_v1_0 *receivers; 68 uint32_t offset; 69 70 receivers = (struct ffa_emad_v1_0 *) 71 ((uint8_t *) memory_region + 72 memory_region->emad_offset + 73 (memory_region->emad_size * receiver_index)); 74 offset = receivers->comp_mrd_offset; 75 76 if (offset == 0U) { 77 return NULL; 78 } 79 80 return (struct ffa_comp_mrd *) 81 ((uint8_t *) memory_region + offset); 82 } 83 84 static inline uint32_t ffa_get_data_access_attr(ffa_mem_perm8_t perm) 85 { 86 return ((perm >> FFA_MEM_PERM_DATA_OFFSET) & FFA_MEM_PERM_DATA_MASK); 87 } 88 89 smc_args_t ffa_mem_frag_rx(uint64_t handle, uint32_t recv_length); 90 bool ffa_mem_relinquish(void); 91 bool ffa_rx_release(void); 92 bool memory_relinquish(struct ffa_mem_relinquish_descriptor *m, uint64_t handle, 93 ffa_endpoint_id16_t id); 94 bool ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages); 95 bool memory_retrieve(struct mailbox *mb, 96 struct ffa_mtd **retrieved, 97 uint64_t handle, ffa_endpoint_id16_t sender, 98 ffa_endpoint_id16_t *receivers, uint32_t receiver_count, 99 ffa_mtd_flag32_t flags, uint32_t *frag_length, 100 uint32_t *total_length); 101 102 smc_args_t ffa_msg_send_direct_req(ffa_endpoint_id16_t sender, 103 ffa_endpoint_id16_t receiver, 104 uint32_t arg3, 105 uint32_t arg4, 106 uint32_t arg5, 107 uint32_t arg6, 108 uint32_t arg7); 109 smc_args_t *ffa_msg_send_direct_resp(ffa_endpoint_id16_t sender, 110 ffa_endpoint_id16_t receiver, 111 uint32_t arg3, 112 uint32_t arg4, 113 uint32_t arg5, 114 uint32_t arg6, 115 uint32_t arg7); 116 #endif /* FFA_HELPERS_H */ 117