1 /* 2 * Copyright (c) 2022, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <common/debug.h> 8 #include "ffa_helpers.h" 9 #include <services/ffa_svc.h> 10 #include "tsp_private.h" 11 12 /** 13 * Initialises the header of the given `ffa_mtd`, not including the 14 * composite memory region offset. 15 */ 16 static void ffa_memory_region_init_header( 17 struct ffa_mtd *memory_region, ffa_endpoint_id16_t sender, 18 ffa_mem_attr16_t attributes, ffa_mtd_flag32_t flags, 19 uint64_t handle, uint64_t tag, ffa_endpoint_id16_t *receivers, 20 uint32_t receiver_count, ffa_mem_perm8_t permissions) 21 { 22 struct ffa_emad_v1_0 *emad; 23 24 memory_region->emad_offset = sizeof(struct ffa_mtd); 25 memory_region->emad_size = sizeof(struct ffa_emad_v1_0); 26 emad = (struct ffa_emad_v1_0 *) 27 ((uint8_t *) memory_region + 28 memory_region->emad_offset); 29 memory_region->sender_id = sender; 30 memory_region->memory_region_attributes = attributes; 31 memory_region->reserved_36_39 = 0; 32 memory_region->flags = flags; 33 memory_region->handle = handle; 34 memory_region->tag = tag; 35 memory_region->reserved_40_47 = 0; 36 memory_region->emad_count = receiver_count; 37 for (uint32_t i = 0U; i < receiver_count; i++) { 38 emad[i].mapd.endpoint_id = receivers[i]; 39 emad[i].mapd.memory_access_permissions = permissions; 40 emad[i].mapd.flags = 0; 41 emad[i].comp_mrd_offset = 0; 42 emad[i].reserved_8_15 = 0; 43 } 44 } 45 /** 46 * Initialises the given `ffa_mtd` to be used for an 47 * `FFA_MEM_RETRIEVE_REQ` by the receiver of a memory transaction. 48 * TODO: Support differing attributes per receiver. 49 * 50 * Returns the size of the descriptor written. 51 */ 52 uint32_t ffa_memory_retrieve_request_init( 53 struct ffa_mtd *memory_region, uint64_t handle, 54 ffa_endpoint_id16_t sender, ffa_endpoint_id16_t *receivers, uint32_t receiver_count, 55 uint64_t tag, ffa_mtd_flag32_t flags, 56 ffa_mem_perm8_t permissions, 57 ffa_mem_attr16_t attributes) 58 { 59 ffa_memory_region_init_header(memory_region, sender, attributes, flags, 60 handle, tag, receivers, 61 receiver_count, permissions); 62 63 return sizeof(struct ffa_mtd) + 64 memory_region->emad_count * sizeof(struct ffa_emad_v1_0); 65 } 66 67 /* Relinquish access to memory region. */ 68 bool ffa_mem_relinquish(void) 69 { 70 smc_args_t ret; 71 72 ret = smc_helper(FFA_MEM_RELINQUISH, 0, 0, 0, 0, 0, 0, 0); 73 if (ffa_func_id(ret) != FFA_SUCCESS_SMC32) { 74 ERROR("%s failed to relinquish memory! error: (%x) %x\n", 75 __func__, ffa_func_id(ret), ffa_error_code(ret)); 76 return false; 77 } 78 return true; 79 } 80 81 /* Retrieve memory shared by another partition. */ 82 smc_args_t ffa_mem_retrieve_req(uint32_t descriptor_length, 83 uint32_t fragment_length) 84 { 85 return smc_helper(FFA_MEM_RETRIEVE_REQ_SMC32, 86 descriptor_length, 87 fragment_length, 88 0, 0, 0, 0, 0); 89 } 90 91 /* Retrieve the next memory descriptor fragment. */ 92 smc_args_t ffa_mem_frag_rx(uint64_t handle, uint32_t recv_length) 93 { 94 return smc_helper(FFA_MEM_FRAG_RX, 95 FFA_MEM_HANDLE_LOW(handle), 96 FFA_MEM_HANDLE_HIGH(handle), 97 recv_length, 98 0, 0, 0, 0); 99 } 100 101 /* Relinquish the memory region. */ 102 bool memory_relinquish(struct ffa_mem_relinquish_descriptor *m, uint64_t handle, 103 ffa_endpoint_id16_t id) 104 { 105 ffa_mem_relinquish_init(m, handle, 0, id); 106 return ffa_mem_relinquish(); 107 } 108 109 /* Query SPMC that the rx buffer of the partition can be released. */ 110 bool ffa_rx_release(void) 111 { 112 smc_args_t ret; 113 114 ret = smc_helper(FFA_RX_RELEASE, 0, 0, 0, 0, 0, 0, 0); 115 return ret._regs[SMC_ARG0] != FFA_SUCCESS_SMC32; 116 } 117 118 /* Map the provided buffers with the SPMC. */ 119 bool ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages) 120 { 121 smc_args_t ret; 122 123 ret = smc_helper(FFA_RXTX_MAP_SMC64, send, recv, pages, 0, 0, 0, 0); 124 return ret._regs[0] != FFA_SUCCESS_SMC32; 125 } 126