xref: /aosp_15_r20/trusty/kernel/lib/sm/shared_mem.c (revision 344aa361028b423587d4ef3fa52a23d194628137)
1*344aa361SAndroid Build Coastguard Worker /*
2*344aa361SAndroid Build Coastguard Worker  * Copyright (c) 2019-2020 LK Trusty Authors. All Rights Reserved.
3*344aa361SAndroid Build Coastguard Worker  *
4*344aa361SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining
5*344aa361SAndroid Build Coastguard Worker  * a copy of this software and associated documentation files
6*344aa361SAndroid Build Coastguard Worker  * (the "Software"), to deal in the Software without restriction,
7*344aa361SAndroid Build Coastguard Worker  * including without limitation the rights to use, copy, modify, merge,
8*344aa361SAndroid Build Coastguard Worker  * publish, distribute, sublicense, and/or sell copies of the Software,
9*344aa361SAndroid Build Coastguard Worker  * and to permit persons to whom the Software is furnished to do so,
10*344aa361SAndroid Build Coastguard Worker  * subject to the following conditions:
11*344aa361SAndroid Build Coastguard Worker  *
12*344aa361SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be
13*344aa361SAndroid Build Coastguard Worker  * included in all copies or substantial portions of the Software.
14*344aa361SAndroid Build Coastguard Worker  *
15*344aa361SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*344aa361SAndroid Build Coastguard Worker  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*344aa361SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18*344aa361SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19*344aa361SAndroid Build Coastguard Worker  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20*344aa361SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21*344aa361SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*344aa361SAndroid Build Coastguard Worker  */
23*344aa361SAndroid Build Coastguard Worker 
24*344aa361SAndroid Build Coastguard Worker #include <compiler.h>
25*344aa361SAndroid Build Coastguard Worker #include <debug.h>
26*344aa361SAndroid Build Coastguard Worker #include <err.h>
27*344aa361SAndroid Build Coastguard Worker #include <interface/arm_ffa/arm_ffa.h>
28*344aa361SAndroid Build Coastguard Worker #include <inttypes.h>
29*344aa361SAndroid Build Coastguard Worker #include <kernel/mutex.h>
30*344aa361SAndroid Build Coastguard Worker #include <kernel/vm.h>
31*344aa361SAndroid Build Coastguard Worker #include <lib/arm_ffa/arm_ffa.h>
32*344aa361SAndroid Build Coastguard Worker #include <lib/extmem/extmem.h>
33*344aa361SAndroid Build Coastguard Worker #include <lib/page_alloc.h>
34*344aa361SAndroid Build Coastguard Worker #include <lib/sm.h>
35*344aa361SAndroid Build Coastguard Worker #include <lib/smc/smc.h>
36*344aa361SAndroid Build Coastguard Worker #include <lk/init.h>
37*344aa361SAndroid Build Coastguard Worker #include <string.h>
38*344aa361SAndroid Build Coastguard Worker #include <sys/types.h>
39*344aa361SAndroid Build Coastguard Worker #include <trace.h>
40*344aa361SAndroid Build Coastguard Worker 
41*344aa361SAndroid Build Coastguard Worker #define LOCAL_TRACE 0
42*344aa361SAndroid Build Coastguard Worker 
43*344aa361SAndroid Build Coastguard Worker struct sm_mem_obj {
44*344aa361SAndroid Build Coastguard Worker     uint16_t sender_id;
45*344aa361SAndroid Build Coastguard Worker     struct ext_mem_obj ext_mem_obj;
46*344aa361SAndroid Build Coastguard Worker };
47*344aa361SAndroid Build Coastguard Worker 
sm_mem_obj_compat_destroy(struct vmm_obj * vmm_obj)48*344aa361SAndroid Build Coastguard Worker static void sm_mem_obj_compat_destroy(struct vmm_obj* vmm_obj) {
49*344aa361SAndroid Build Coastguard Worker     struct ext_mem_obj* obj = containerof(vmm_obj, struct ext_mem_obj, vmm_obj);
50*344aa361SAndroid Build Coastguard Worker     free(obj);
51*344aa361SAndroid Build Coastguard Worker }
52*344aa361SAndroid Build Coastguard Worker 
53*344aa361SAndroid Build Coastguard Worker static struct vmm_obj_ops sm_mem_obj_compat_ops = {
54*344aa361SAndroid Build Coastguard Worker         .check_flags = ext_mem_obj_check_flags,
55*344aa361SAndroid Build Coastguard Worker         .get_page = ext_mem_obj_get_page,
56*344aa361SAndroid Build Coastguard Worker         .destroy = sm_mem_obj_compat_destroy,
57*344aa361SAndroid Build Coastguard Worker };
58*344aa361SAndroid Build Coastguard Worker 
59*344aa361SAndroid Build Coastguard Worker /**
60*344aa361SAndroid Build Coastguard Worker  * sm_mem_compat_get_vmm_obj - Create vmm_obj from id.
61*344aa361SAndroid Build Coastguard Worker  * @client_id:  Id of external entity where the memory originated.
62*344aa361SAndroid Build Coastguard Worker  * @mem_obj_id: Object id containing a packed address and attibutes.
63*344aa361SAndroid Build Coastguard Worker  * @size:       Size of object.
64*344aa361SAndroid Build Coastguard Worker  * @objp:       Pointer to return object in.
65*344aa361SAndroid Build Coastguard Worker  * @obj_ref:    Reference to *@objp.
66*344aa361SAndroid Build Coastguard Worker  *
67*344aa361SAndroid Build Coastguard Worker  * The object paddr and attibutes are encoded in the id for now. Convert it to a
68*344aa361SAndroid Build Coastguard Worker  * paddr and mmu-flags using the existing helper function.
69*344aa361SAndroid Build Coastguard Worker  *
70*344aa361SAndroid Build Coastguard Worker  * Return: 0 on success, negative error code if object could not be created.
71*344aa361SAndroid Build Coastguard Worker  */
sm_mem_compat_get_vmm_obj(ext_mem_client_id_t client_id,ext_mem_obj_id_t mem_obj_id,size_t size,struct vmm_obj ** objp,struct obj_ref * obj_ref)72*344aa361SAndroid Build Coastguard Worker static status_t sm_mem_compat_get_vmm_obj(ext_mem_client_id_t client_id,
73*344aa361SAndroid Build Coastguard Worker                                           ext_mem_obj_id_t mem_obj_id,
74*344aa361SAndroid Build Coastguard Worker                                           size_t size,
75*344aa361SAndroid Build Coastguard Worker                                           struct vmm_obj** objp,
76*344aa361SAndroid Build Coastguard Worker                                           struct obj_ref* obj_ref) {
77*344aa361SAndroid Build Coastguard Worker     int ret;
78*344aa361SAndroid Build Coastguard Worker     struct ext_mem_obj* obj;
79*344aa361SAndroid Build Coastguard Worker     struct ns_page_info pinf = {mem_obj_id};
80*344aa361SAndroid Build Coastguard Worker     ns_addr_t ns_paddr;
81*344aa361SAndroid Build Coastguard Worker     paddr_t paddr;
82*344aa361SAndroid Build Coastguard Worker     uint arch_mmu_flags;
83*344aa361SAndroid Build Coastguard Worker 
84*344aa361SAndroid Build Coastguard Worker     ret = sm_decode_ns_memory_attr(&pinf, &ns_paddr, &arch_mmu_flags);
85*344aa361SAndroid Build Coastguard Worker     if (ret) {
86*344aa361SAndroid Build Coastguard Worker         return ret;
87*344aa361SAndroid Build Coastguard Worker     }
88*344aa361SAndroid Build Coastguard Worker 
89*344aa361SAndroid Build Coastguard Worker     paddr = (paddr_t)ns_paddr;
90*344aa361SAndroid Build Coastguard Worker     if (paddr != ns_paddr) {
91*344aa361SAndroid Build Coastguard Worker         /*
92*344aa361SAndroid Build Coastguard Worker          * If ns_addr_t is larger than paddr_t and we get an address that does
93*344aa361SAndroid Build Coastguard Worker          * not fit, return an error as we cannot map that address.
94*344aa361SAndroid Build Coastguard Worker          */
95*344aa361SAndroid Build Coastguard Worker         TRACEF("unsupported paddr, 0x%0" PRIxNS_ADDR "\n", ns_paddr);
96*344aa361SAndroid Build Coastguard Worker         return ERR_INVALID_ARGS;
97*344aa361SAndroid Build Coastguard Worker     }
98*344aa361SAndroid Build Coastguard Worker 
99*344aa361SAndroid Build Coastguard Worker     obj = malloc(sizeof(*obj) + ext_mem_obj_page_runs_size(1));
100*344aa361SAndroid Build Coastguard Worker     if (!obj) {
101*344aa361SAndroid Build Coastguard Worker         return ERR_NO_MEMORY;
102*344aa361SAndroid Build Coastguard Worker     }
103*344aa361SAndroid Build Coastguard Worker 
104*344aa361SAndroid Build Coastguard Worker     arch_mmu_flags |= ARCH_MMU_FLAG_NS | ARCH_MMU_FLAG_PERM_NO_EXECUTE;
105*344aa361SAndroid Build Coastguard Worker     ext_mem_obj_initialize(obj, obj_ref, mem_obj_id, 0, &sm_mem_obj_compat_ops,
106*344aa361SAndroid Build Coastguard Worker                            arch_mmu_flags, 1);
107*344aa361SAndroid Build Coastguard Worker     obj->page_runs[0].paddr = paddr;
108*344aa361SAndroid Build Coastguard Worker     obj->page_runs[0].size = size;
109*344aa361SAndroid Build Coastguard Worker     *objp = &obj->vmm_obj;
110*344aa361SAndroid Build Coastguard Worker 
111*344aa361SAndroid Build Coastguard Worker     return 0;
112*344aa361SAndroid Build Coastguard Worker }
113*344aa361SAndroid Build Coastguard Worker 
114*344aa361SAndroid Build Coastguard Worker /**
115*344aa361SAndroid Build Coastguard Worker  * sm_mem_obj_destroy: Destroy memory object.
116*344aa361SAndroid Build Coastguard Worker  * @vmm_obj:    VMM object to destroy.
117*344aa361SAndroid Build Coastguard Worker  *
118*344aa361SAndroid Build Coastguard Worker  * Called after the last reference to @vmm_obj has been released. Relinquish
119*344aa361SAndroid Build Coastguard Worker  * shared memory object id with SPM/Hypervisor and free local tracking object.
120*344aa361SAndroid Build Coastguard Worker  */
sm_mem_obj_destroy(struct vmm_obj * vmm_obj)121*344aa361SAndroid Build Coastguard Worker static void sm_mem_obj_destroy(struct vmm_obj* vmm_obj) {
122*344aa361SAndroid Build Coastguard Worker     int ret;
123*344aa361SAndroid Build Coastguard Worker     struct sm_mem_obj* obj =
124*344aa361SAndroid Build Coastguard Worker             containerof(vmm_obj, struct sm_mem_obj, ext_mem_obj.vmm_obj);
125*344aa361SAndroid Build Coastguard Worker 
126*344aa361SAndroid Build Coastguard Worker     DEBUG_ASSERT(obj);
127*344aa361SAndroid Build Coastguard Worker 
128*344aa361SAndroid Build Coastguard Worker     ret = arm_ffa_mem_relinquish(obj->ext_mem_obj.id);
129*344aa361SAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
130*344aa361SAndroid Build Coastguard Worker         TRACEF("Failed to relinquish the shared memory (%d)\n", ret);
131*344aa361SAndroid Build Coastguard Worker     }
132*344aa361SAndroid Build Coastguard Worker 
133*344aa361SAndroid Build Coastguard Worker     free(obj);
134*344aa361SAndroid Build Coastguard Worker }
135*344aa361SAndroid Build Coastguard Worker 
136*344aa361SAndroid Build Coastguard Worker static struct vmm_obj_ops sm_mem_obj_ops = {
137*344aa361SAndroid Build Coastguard Worker         .check_flags = ext_mem_obj_check_flags,
138*344aa361SAndroid Build Coastguard Worker         .get_page = ext_mem_obj_get_page,
139*344aa361SAndroid Build Coastguard Worker         .destroy = sm_mem_obj_destroy,
140*344aa361SAndroid Build Coastguard Worker };
141*344aa361SAndroid Build Coastguard Worker 
142*344aa361SAndroid Build Coastguard Worker /**
143*344aa361SAndroid Build Coastguard Worker  * sm_mem_alloc_obj - Allocate and initialize memory object.
144*344aa361SAndroid Build Coastguard Worker  * @sender_id:      FF-A vm id of sender.
145*344aa361SAndroid Build Coastguard Worker  * @mem_id:         Id of object.
146*344aa361SAndroid Build Coastguard Worker  * @tag:            Tag of the object
147*344aa361SAndroid Build Coastguard Worker  * @page_run_count: Number of page runs to allocate for object.
148*344aa361SAndroid Build Coastguard Worker  * @arch_mmu_flags: Memory type and permissions.
149*344aa361SAndroid Build Coastguard Worker  * @obj_ref:        Reference to returned object.
150*344aa361SAndroid Build Coastguard Worker  *
151*344aa361SAndroid Build Coastguard Worker  * Return: Pointer to &struct sm_mem_obj, or %NULL if allocation fails.
152*344aa361SAndroid Build Coastguard Worker  */
sm_mem_alloc_obj(uint16_t sender_id,ext_mem_obj_id_t mem_id,uint64_t tag,size_t page_run_count,uint arch_mmu_flags,struct obj_ref * obj_ref)153*344aa361SAndroid Build Coastguard Worker static struct sm_mem_obj* sm_mem_alloc_obj(uint16_t sender_id,
154*344aa361SAndroid Build Coastguard Worker                                            ext_mem_obj_id_t mem_id,
155*344aa361SAndroid Build Coastguard Worker                                            uint64_t tag,
156*344aa361SAndroid Build Coastguard Worker                                            size_t page_run_count,
157*344aa361SAndroid Build Coastguard Worker                                            uint arch_mmu_flags,
158*344aa361SAndroid Build Coastguard Worker                                            struct obj_ref* obj_ref) {
159*344aa361SAndroid Build Coastguard Worker     struct sm_mem_obj* obj =
160*344aa361SAndroid Build Coastguard Worker             malloc(sizeof(*obj) + ext_mem_obj_page_runs_size(page_run_count));
161*344aa361SAndroid Build Coastguard Worker     if (!obj) {
162*344aa361SAndroid Build Coastguard Worker         return NULL;
163*344aa361SAndroid Build Coastguard Worker     }
164*344aa361SAndroid Build Coastguard Worker     ext_mem_obj_initialize(&obj->ext_mem_obj, obj_ref, mem_id, tag,
165*344aa361SAndroid Build Coastguard Worker                            &sm_mem_obj_ops, arch_mmu_flags, page_run_count);
166*344aa361SAndroid Build Coastguard Worker     obj->sender_id = sender_id;
167*344aa361SAndroid Build Coastguard Worker 
168*344aa361SAndroid Build Coastguard Worker     return obj;
169*344aa361SAndroid Build Coastguard Worker }
170*344aa361SAndroid Build Coastguard Worker 
171*344aa361SAndroid Build Coastguard Worker /* sm_mem_get_vmm_obj - Looks up a shared memory object using FF-A.
172*344aa361SAndroid Build Coastguard Worker  * @client_id:      Id of external entity where the memory originated.
173*344aa361SAndroid Build Coastguard Worker  * @mem_obj_id:     Id of shared memory object to lookup and return.
174*344aa361SAndroid Build Coastguard Worker  * @tag:            Tag of the memory.
175*344aa361SAndroid Build Coastguard Worker  * @size:           Size hint for object. Caller expects an object at least this
176*344aa361SAndroid Build Coastguard Worker  *                  big.
177*344aa361SAndroid Build Coastguard Worker  * @objp:           Pointer to return object in.
178*344aa361SAndroid Build Coastguard Worker  * @obj_ref:        Reference to *@objp.
179*344aa361SAndroid Build Coastguard Worker  *
180*344aa361SAndroid Build Coastguard Worker  * Return: 0 on success. ERR_NOT_FOUND if @id does not exist.
181*344aa361SAndroid Build Coastguard Worker  */
sm_mem_get_vmm_obj(ext_mem_client_id_t client_id,ext_mem_obj_id_t mem_obj_id,uint64_t tag,size_t size,struct vmm_obj ** objp,struct obj_ref * obj_ref)182*344aa361SAndroid Build Coastguard Worker static status_t sm_mem_get_vmm_obj(ext_mem_client_id_t client_id,
183*344aa361SAndroid Build Coastguard Worker                                    ext_mem_obj_id_t mem_obj_id,
184*344aa361SAndroid Build Coastguard Worker                                    uint64_t tag,
185*344aa361SAndroid Build Coastguard Worker                                    size_t size,
186*344aa361SAndroid Build Coastguard Worker                                    struct vmm_obj** objp,
187*344aa361SAndroid Build Coastguard Worker                                    struct obj_ref* obj_ref) {
188*344aa361SAndroid Build Coastguard Worker     int ret;
189*344aa361SAndroid Build Coastguard Worker     struct arm_ffa_mem_frag_info frag_info;
190*344aa361SAndroid Build Coastguard Worker     uint32_t address_range_count;
191*344aa361SAndroid Build Coastguard Worker     uint arch_mmu_flags;
192*344aa361SAndroid Build Coastguard Worker     struct sm_mem_obj* obj;
193*344aa361SAndroid Build Coastguard Worker     struct obj_ref tmp_obj_ref = OBJ_REF_INITIAL_VALUE(tmp_obj_ref);
194*344aa361SAndroid Build Coastguard Worker 
195*344aa361SAndroid Build Coastguard Worker     DEBUG_ASSERT(objp);
196*344aa361SAndroid Build Coastguard Worker     DEBUG_ASSERT(obj_ref);
197*344aa361SAndroid Build Coastguard Worker 
198*344aa361SAndroid Build Coastguard Worker     if ((client_id & 0xffff) != client_id) {
199*344aa361SAndroid Build Coastguard Worker         TRACEF("Invalid client ID\n");
200*344aa361SAndroid Build Coastguard Worker         return ERR_INVALID_ARGS;
201*344aa361SAndroid Build Coastguard Worker     }
202*344aa361SAndroid Build Coastguard Worker 
203*344aa361SAndroid Build Coastguard Worker     ret = arm_ffa_mem_retrieve_start((uint16_t)client_id, mem_obj_id, tag,
204*344aa361SAndroid Build Coastguard Worker                                      &address_range_count, &arch_mmu_flags,
205*344aa361SAndroid Build Coastguard Worker                                      &frag_info);
206*344aa361SAndroid Build Coastguard Worker 
207*344aa361SAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
208*344aa361SAndroid Build Coastguard Worker         TRACEF("Failed to get FF-A memory buffer, err=%d\n", ret);
209*344aa361SAndroid Build Coastguard Worker         goto err_mem_get_access;
210*344aa361SAndroid Build Coastguard Worker     }
211*344aa361SAndroid Build Coastguard Worker     obj = sm_mem_alloc_obj(client_id, mem_obj_id, tag, address_range_count,
212*344aa361SAndroid Build Coastguard Worker                            arch_mmu_flags, &tmp_obj_ref);
213*344aa361SAndroid Build Coastguard Worker     if (!obj) {
214*344aa361SAndroid Build Coastguard Worker         TRACEF("Failed to allocate a shared memory object\n");
215*344aa361SAndroid Build Coastguard Worker         ret = ERR_NO_MEMORY;
216*344aa361SAndroid Build Coastguard Worker         goto err_mem_alloc_obj;
217*344aa361SAndroid Build Coastguard Worker     }
218*344aa361SAndroid Build Coastguard Worker 
219*344aa361SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < address_range_count; i++) {
220*344aa361SAndroid Build Coastguard Worker         if (frag_info.start_index + frag_info.count <= i) {
221*344aa361SAndroid Build Coastguard Worker             arm_ffa_rx_release();
222*344aa361SAndroid Build Coastguard Worker             ret = arm_ffa_mem_retrieve_next_frag(mem_obj_id, &frag_info);
223*344aa361SAndroid Build Coastguard Worker             if (ret != NO_ERROR) {
224*344aa361SAndroid Build Coastguard Worker                 TRACEF("Failed to get next fragment, err=%d\n", ret);
225*344aa361SAndroid Build Coastguard Worker                 goto err_mem_next_frag;
226*344aa361SAndroid Build Coastguard Worker             }
227*344aa361SAndroid Build Coastguard Worker         }
228*344aa361SAndroid Build Coastguard Worker         ret = arm_ffa_mem_address_range_get(
229*344aa361SAndroid Build Coastguard Worker                 &frag_info, i, &obj->ext_mem_obj.page_runs[i].paddr,
230*344aa361SAndroid Build Coastguard Worker                 &obj->ext_mem_obj.page_runs[i].size);
231*344aa361SAndroid Build Coastguard Worker         if (ret != NO_ERROR) {
232*344aa361SAndroid Build Coastguard Worker             TRACEF("Failed to get address range, err=%d\n", ret);
233*344aa361SAndroid Build Coastguard Worker             goto err_mem_address_range;
234*344aa361SAndroid Build Coastguard Worker         }
235*344aa361SAndroid Build Coastguard Worker     }
236*344aa361SAndroid Build Coastguard Worker 
237*344aa361SAndroid Build Coastguard Worker     /* No lock needed as the object is not yet visible to anyone else */
238*344aa361SAndroid Build Coastguard Worker     obj_ref_transfer(obj_ref, &tmp_obj_ref);
239*344aa361SAndroid Build Coastguard Worker     *objp = &obj->ext_mem_obj.vmm_obj;
240*344aa361SAndroid Build Coastguard Worker 
241*344aa361SAndroid Build Coastguard Worker     arm_ffa_rx_release();
242*344aa361SAndroid Build Coastguard Worker 
243*344aa361SAndroid Build Coastguard Worker     return 0;
244*344aa361SAndroid Build Coastguard Worker 
245*344aa361SAndroid Build Coastguard Worker err_mem_address_range:
246*344aa361SAndroid Build Coastguard Worker err_mem_next_frag:
247*344aa361SAndroid Build Coastguard Worker     DEBUG_ASSERT(obj_ref_active(&tmp_obj_ref));
248*344aa361SAndroid Build Coastguard Worker     vmm_obj_del_ref(&obj->ext_mem_obj.vmm_obj, &tmp_obj_ref);
249*344aa361SAndroid Build Coastguard Worker 
250*344aa361SAndroid Build Coastguard Worker err_mem_alloc_obj:
251*344aa361SAndroid Build Coastguard Worker err_mem_get_access:
252*344aa361SAndroid Build Coastguard Worker     arm_ffa_rx_release();
253*344aa361SAndroid Build Coastguard Worker     return ret;
254*344aa361SAndroid Build Coastguard Worker }
255*344aa361SAndroid Build Coastguard Worker 
256*344aa361SAndroid Build Coastguard Worker /*
257*344aa361SAndroid Build Coastguard Worker  * ext_mem_get_vmm_obj - Lookup or create shared memory object.
258*344aa361SAndroid Build Coastguard Worker  * @client_id:  Id of external entity where the memory originated.
259*344aa361SAndroid Build Coastguard Worker  * @mem_obj_id: Id of shared memory object to lookup and return.
260*344aa361SAndroid Build Coastguard Worker  * @tag:        Value to identify the transaction.
261*344aa361SAndroid Build Coastguard Worker  * @size:       Size hint for object.
262*344aa361SAndroid Build Coastguard Worker  * @objp:       Pointer to return object in.
263*344aa361SAndroid Build Coastguard Worker  * @obj_ref:    Reference to *@objp.
264*344aa361SAndroid Build Coastguard Worker  *
265*344aa361SAndroid Build Coastguard Worker  * Call SPM/Hypervisor to retrieve memory region or extract address and
266*344aa361SAndroid Build Coastguard Worker  * attributes from id for old clients.
267*344aa361SAndroid Build Coastguard Worker  */
ext_mem_get_vmm_obj(ext_mem_client_id_t client_id,ext_mem_obj_id_t mem_obj_id,uint64_t tag,size_t size,struct vmm_obj ** objp,struct obj_ref * obj_ref)268*344aa361SAndroid Build Coastguard Worker status_t ext_mem_get_vmm_obj(ext_mem_client_id_t client_id,
269*344aa361SAndroid Build Coastguard Worker                              ext_mem_obj_id_t mem_obj_id,
270*344aa361SAndroid Build Coastguard Worker                              uint64_t tag,
271*344aa361SAndroid Build Coastguard Worker                              size_t size,
272*344aa361SAndroid Build Coastguard Worker                              struct vmm_obj** objp,
273*344aa361SAndroid Build Coastguard Worker                              struct obj_ref* obj_ref) {
274*344aa361SAndroid Build Coastguard Worker     if (sm_get_api_version() >= TRUSTY_API_VERSION_MEM_OBJ) {
275*344aa361SAndroid Build Coastguard Worker         return sm_mem_get_vmm_obj(client_id, mem_obj_id, tag, size, objp,
276*344aa361SAndroid Build Coastguard Worker                                   obj_ref);
277*344aa361SAndroid Build Coastguard Worker     } else if (!client_id && !tag) {
278*344aa361SAndroid Build Coastguard Worker         /* If client is not running under a hypervisor allow using
279*344aa361SAndroid Build Coastguard Worker            old api. */
280*344aa361SAndroid Build Coastguard Worker         return sm_mem_compat_get_vmm_obj(client_id, mem_obj_id, size, objp,
281*344aa361SAndroid Build Coastguard Worker                                          obj_ref);
282*344aa361SAndroid Build Coastguard Worker     } else {
283*344aa361SAndroid Build Coastguard Worker         return ERR_NOT_SUPPORTED;
284*344aa361SAndroid Build Coastguard Worker     }
285*344aa361SAndroid Build Coastguard Worker }
286*344aa361SAndroid Build Coastguard Worker 
287*344aa361SAndroid Build Coastguard Worker /**
288*344aa361SAndroid Build Coastguard Worker  * shared_mem_init - Connect to SPM/Hypervisor.
289*344aa361SAndroid Build Coastguard Worker  * @level:  Unused.
290*344aa361SAndroid Build Coastguard Worker  *
291*344aa361SAndroid Build Coastguard Worker  */
shared_mem_init(uint level)292*344aa361SAndroid Build Coastguard Worker static void shared_mem_init(uint level) {
293*344aa361SAndroid Build Coastguard Worker     /* Check the FF-A module initialized successfully */
294*344aa361SAndroid Build Coastguard Worker     if (!arm_ffa_is_init()) {
295*344aa361SAndroid Build Coastguard Worker         TRACEF("arm_ffa module is not initialized\n");
296*344aa361SAndroid Build Coastguard Worker         if (sm_check_and_lock_api_version(TRUSTY_API_VERSION_MEM_OBJ)) {
297*344aa361SAndroid Build Coastguard Worker             panic("shared_mem_init failed after mem_obj version selected\n");
298*344aa361SAndroid Build Coastguard Worker         }
299*344aa361SAndroid Build Coastguard Worker     }
300*344aa361SAndroid Build Coastguard Worker }
301*344aa361SAndroid Build Coastguard Worker 
302*344aa361SAndroid Build Coastguard Worker LK_INIT_HOOK(shared_mem, shared_mem_init, LK_INIT_LEVEL_APPS);
303