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