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