1 /*
2  * Copyright (c) 2019 LK Trusty Authors. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #pragma once
24 
25 #include <assert.h>
26 #include <lk/reflist.h>
27 #include <sys/types.h>
28 
29 __BEGIN_CDECLS
30 
31 struct vmm_obj;
32 
33 /**
34  * struct vmm_obj_ops - Operation on &struct vmm_obj.
35  */
36 struct vmm_obj_ops {
37     /**
38      * @check_flags: Function to check and optionally modify arch_mmu_flags.
39      *
40      * Check if permission @arch_mmu_flags are allowed and add other flags if
41      * needed.
42      *
43      * If @obj is read-only and ARCH_MMU_FLAG_PERM_RO is not set, return
44      * ERR_ACCESS_DENIED.
45      *
46      * If @obj require a specific memory type (e.g.
47      * ARCH_MMU_FLAG_UNCACHED_DEVICE or ARCH_MMU_FLAG_NS), set those flags.
48      *
49      * Return 0 on success, error code to be passed to caller on failure.
50      */
51     int (*check_flags)(struct vmm_obj *obj, uint *arch_mmu_flags);
52     /**
53      * @get_page: Function to get a page address.
54      *
55      * Get single page or physically contiguous region at @offset bytes from
56      * start of @obj.
57      *
58      * Return 0 on success, error code to be passed to caller on failure.
59      */
60     int (*get_page)(struct vmm_obj *obj, size_t offset, paddr_t *paddr,
61                     size_t *paddr_size);
62     /**
63      * @destroy: Function to destroy object.
64      *
65      * Called after the last reference to @obj has been released.
66      */
67     void (*destroy)(struct vmm_obj *obj);
68 };
69 
70 /**
71  * struct vmm_obj - Object mappable by vmm.
72  * @obj: Reflist object.
73  * @ops: Pointer to &struct vmm_obj_ops.
74  */
75 struct vmm_obj {
76     struct obj obj;
77     struct vmm_obj_ops *ops;
78 };
79 
80 /**
81  * vmm_obj_init - Initialize &struct vmm_obj.
82  * @obj: Object to initialise and add reference to.
83  * @ref: Reference to add.
84  * @ops: Pointer to &struct vmm_obj_ops.
85  */
vmm_obj_init(struct vmm_obj * obj,struct obj_ref * ref,struct vmm_obj_ops * ops)86 static inline __ALWAYS_INLINE void vmm_obj_init(struct vmm_obj *obj,
87                                                 struct obj_ref *ref,
88                                                 struct vmm_obj_ops *ops) {
89     DEBUG_ASSERT(ops->check_flags);
90     DEBUG_ASSERT(ops->get_page);
91     DEBUG_ASSERT(ops->destroy);
92     obj->ops = ops;
93     obj_init(&obj->obj, ref);
94 }
95 
96 /**
97  * vmm_obj_del_ref - Add a reference to a vmm_obj.
98  * @obj: Object to add reference to.
99  * @ref: Reference to add.
100  */
101 void vmm_obj_add_ref(struct vmm_obj *obj, struct obj_ref *ref);
102 
103 /**
104  * vmm_obj_del_ref - Remove reference. Destroy object if no references remain.
105  * @obj: Object to remove reference from.
106  * @ref: Reference to remove.
107  */
108 void vmm_obj_del_ref(struct vmm_obj *obj, struct obj_ref *ref);
109 
110 /**
111  * vmm_obj_has_single_ref - Return whether a &struct vmm_obj has a single
112  *                          reference to it.
113  * @obj: Object to check for single reference.
114  * @ref: Reference to check. Must be a reference to @obj.
115  *
116  * The result from this function may become invalid if references are added or
117  * deleted after this function returns, either by the caller or other threads.
118  */
119 bool vmm_obj_has_only_ref(struct vmm_obj *obj, struct obj_ref *ref);
120 
121 __END_CDECLS
122