1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2021, Arm Limited.
4  */
5 
6 #ifndef __MM_SP_MEM_H
7 #define __MM_SP_MEM_H
8 
9 #include <ffa.h>
10 #include <mm/fobj.h>
11 #include <sys/queue.h>
12 
13 struct sp_mem;
14 
15 /*
16  * struct sp_mem_receiver - Memory object instance for a FF-A receiver endpoint
17  *
18  * @perm: Receiver permission on the shared memory
19  * @ref_count: Count retrieve requests from endpoint
20  * @smem: Shared memory reference
21  * @link: Link in related list
22  */
23 struct sp_mem_receiver {
24 	struct ffa_mem_access_perm perm;
25 	uint8_t ref_count;
26 	struct sp_mem *smem;
27 
28 	SLIST_ENTRY(sp_mem_receiver) link;
29 };
30 
31 /*
32  * sp_mem_map_region represents the memory address when using FF-A shares.
33  * Instead of storing the physical addresses and the size of the region, we use
34  * the mobj's which were already used by the SPs. The offset is used to point
35  * to the specific location inside the mobj memory range.
36  */
37 struct sp_mem_map_region {
38 	struct mobj *mobj;
39 	/*
40 	 * Offset (in pages) inside the mobj which is used to retrieve the
41 	 * location.
42 	 */
43 	uint32_t page_offset;
44 	uint32_t page_count;
45 
46 	SLIST_ENTRY(sp_mem_map_region) link;
47 };
48 
49 SLIST_HEAD(sp_mem_receiver_head, sp_mem_receiver);
50 SLIST_HEAD(sp_mem_regions_head, sp_mem_map_region);
51 
52 /*
53  * sp_mem is used as the main place to store the FF-A shares information.
54  * For each FFA_SHARE message a new sp_mem object is created.
55  * The receivers field is used to store all receiver specific information.
56  * The regions field is used to store all data needed for retrieving the
57  * shared addresses.
58  */
59 struct sp_mem {
60 	struct sp_mem_regions_head regions;
61 	struct sp_mem_receiver_head receivers;
62 	/* Data which was passed inside struct ffa_mem_transaction */
63 	uint16_t sender_id;
64 	uint8_t mem_reg_attr;
65 	uint32_t flags;
66 	uint64_t global_handle;
67 	uint64_t tag;
68 
69 	SLIST_ENTRY(sp_mem) link;
70 };
71 
72 struct sp_mem *sp_mem_new(void);
73 struct sp_mem_receiver *sp_mem_get_receiver(uint32_t s_id, struct sp_mem *smem);
74 struct sp_mem *sp_mem_get(uint64_t handle);
75 
76 bool sp_mem_is_shared(struct sp_mem_map_region *new_reg);
77 void *sp_mem_get_va(const struct user_mode_ctx *uctx, size_t offset,
78 		    struct mobj *mobj);
79 void sp_mem_remove(struct sp_mem *s_mem);
80 void sp_mem_add(struct sp_mem *smem);
81 struct mobj *sp_mem_new_mobj(uint64_t pages);
82 int sp_mem_add_pages(struct mobj *mobj, unsigned int *idx,
83 		     paddr_t pa, unsigned int num_pages);
84 #endif /*__MM_SP_MEM_H*/
85