1 /**
2  * \file
3  * \brief   Region map interface, C interface.
4  */
5 /*
6  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7  *               Alexander Warg <warg@os.inf.tu-dresden.de>
8  *     economic rights: Technische Universität Dresden (Germany)
9  *
10  * This file is part of TUD:OS and distributed under the terms of the
11  * GNU General Public License 2.
12  * Please see the COPYING-GPL-2 file for details.
13  *
14  * As a special exception, you may use this file as part of a free software
15  * library without restriction.  Specifically, if other files instantiate
16  * templates or use macros or inline functions from this file, or you compile
17  * this file and link it with other files to produce an executable, this
18  * file does not by itself cause the resulting executable to be covered by
19  * the GNU General Public License.  This exception does not however
20  * invalidate any other reasons why the executable file might be covered by
21  * the GNU General Public License.
22  */
23 #pragma once
24 
25 /**
26  * \defgroup api_l4re_c_rm Region map interface
27  * \ingroup api_l4re_c
28  * \brief Region map C interface.
29  */
30 
31 #include <l4/re/env.h>
32 #include <l4/re/c/dataspace.h>
33 
34 EXTERN_C_BEGIN
35 
36 /**
37  * \brief Flags for region operations.
38  * \ingroup api_l4re_c_rm
39  */
40 enum l4re_rm_flags_values {
41   L4RE_RM_F_R    = L4RE_DS_F_R, /**< Region is read-only */
42   L4RE_RM_F_W    = L4RE_DS_F_W,
43   L4RE_RM_F_X    = L4RE_DS_F_X,
44   L4RE_RM_F_RX   = L4RE_DS_F_RX,
45   L4RE_RM_F_RW   = L4RE_DS_F_RW,
46   L4RE_RM_F_RWX  = L4RE_DS_F_RWX,
47 
48   L4RE_RM_F_NO_ALIAS     = 0x200, /**< The region contains exclusive memory that is not mapped anywhere else */
49   L4RE_RM_F_PAGER        = 0x400, /**< Region has a pager */
50   L4RE_RM_F_RESERVED     = 0x800, /**< Region is reserved (blocked) */
51 
52   L4RE_RM_CACHING_SHIFT    = 4, /**< Start of region mapper cache bits */
53 
54   /** Mask of all region manager cache bits */
55   L4RE_RM_F_CACHING      = L4RE_DS_F_CACHING_MASK,
56 
57   L4RE_RM_REGION_FLAGS = 0xffff, /**< Mask of all region flags */
58 
59   /** Cache bits for normal cacheable memory */
60   L4RE_RM_F_CACHE_NORMAL   = L4RE_DS_F_NORMAL,
61 
62   /** Cache bits for buffered (write combining) memory */
63   L4RE_RM_F_CACHE_BUFFERED = L4RE_DS_F_BUFFERABLE,
64 
65   /** Cache bits for uncached memory */
66   L4RE_RM_F_CACHE_UNCACHED = L4RE_DS_F_UNCACHEABLE,
67 
68   L4RE_RM_F_SEARCH_ADDR  = 0x20000, /**< Search for a suitable address range */
69   L4RE_RM_F_IN_AREA      = 0x40000, /**< Search only in area, or map into area */
70   L4RE_RM_F_EAGER_MAP    = 0x80000, /**< Eagerly map the attached data space in. */
71   L4RE_RM_F_ATTACH_FLAGS = 0xf0000, /**< Mask of all attach flags */
72 };
73 
74 typedef l4_uint32_t l4re_rm_flags_t;
75 typedef l4_uint64_t l4re_rm_offset_t;
76 
77 /**
78  * \ingroup api_l4re_c_rm
79  * \return 0 on success, <0 on error
80  * \see L4Re::Rm::reserve_area
81  *
82  * This function is using the L4::Env::env()->rm() service.
83  */
84 L4_CV L4_INLINE int
85 l4re_rm_reserve_area(l4_addr_t *start, unsigned long size,
86                      l4re_rm_flags_t flags, unsigned char align) L4_NOTHROW;
87 
88 /**
89  * \ingroup api_l4re_c_rm
90  * \return 0 on success, <0 on error
91  * \see L4Re::Rm::free_area
92  *
93  * This function is using the L4::Env::env()->rm() service.
94  */
95 L4_CV L4_INLINE int
96 l4re_rm_free_area(l4_addr_t addr) L4_NOTHROW;
97 
98 /**
99  * \ingroup api_l4re_c_rm
100  * \copydetails L4Re::Rm::attach
101  * \return 0 on success, <0 on error
102  * \see L4Re::Rm::attach
103  *
104  * This function is using the L4::Env::env()->rm() service.
105  */
106 L4_CV L4_INLINE int
107 l4re_rm_attach(void **start, unsigned long size, l4re_rm_flags_t flags,
108                l4re_ds_t mem,
109                l4re_rm_offset_t offs,
110                unsigned char align) L4_NOTHROW;
111 
112 
113 /**
114  * \ingroup api_l4re_c_rm
115  * \brief Detach and unmap in current task.
116  * \param addr   Address of the region to detach.
117  * \return 0 on success, <0 on error
118  *
119  * Also \see L4Re::Rm::detach
120  *
121  * This function is using the L4::Env::env()->rm() service.
122  */
123 L4_CV L4_INLINE int
124 l4re_rm_detach(void *addr) L4_NOTHROW;
125 
126 /**
127  * \ingroup api_l4re_c_rm
128  * \brief Detach, unmap and return affected dataspace in current task.
129  * \param addr   Address of the region to detach.
130  * \retval ds    Returns dataspace that is affected.
131  *
132  * \return 0 on success, <0 on error
133  *
134  * Also \see L4Re::Rm::detach
135  *
136  * This function is using the L4::Env::env()->rm() service.
137  */
138 L4_CV L4_INLINE int
139 l4re_rm_detach_ds(void *addr, l4re_ds_t *ds) L4_NOTHROW;
140 
141 /**
142  * \ingroup api_l4re_c_rm
143  * \brief Detach and unmap in specified task.
144  * \param addr   Address of the region to detach.
145  * \param task   Task to unmap pages from, specify L4_INVALID_CAP to not unmap
146  * \return 0 on success, <0 on error
147  *
148  * Also \see L4Re::Rm::detach
149  *
150  * This function is using the L4::Env::env()->rm() service.
151  */
152 L4_CV L4_INLINE int
153 l4re_rm_detach_unmap(l4_addr_t addr, l4_cap_idx_t task) L4_NOTHROW;
154 
155 /**
156  * \ingroup api_l4re_c_rm
157  * \brief Detach and unmap in specified task.
158  * \param addr   Address of the region to detach.
159  * \retval ds    Returns dataspace that is affected.
160  * \param task   Task to unmap pages from, specify L4_INVALID_CAP to not unmap
161  * \return 0 on success, <0 on error
162  *
163  * Also \see L4Re::Rm::detach
164  *
165  * This function is using the L4::Env::env()->rm() service.
166  */
167 L4_CV L4_INLINE int
168 l4re_rm_detach_ds_unmap(void *addr, l4re_ds_t *ds,
169                         l4_cap_idx_t task) L4_NOTHROW;
170 
171 
172 /**
173  * \ingroup api_l4re_c_rm
174  * \return 0 on success, <0 on error
175  * \see L4Re::Rm::find
176  */
177 L4_CV L4_INLINE int
178 l4re_rm_find(l4_addr_t *addr, unsigned long *size,
179              l4re_rm_offset_t *offset,
180              l4re_rm_flags_t *flags, l4re_ds_t *m) L4_NOTHROW;
181 
182 /**
183  * \ingroup api_l4re_c_rm
184  * \brief Dump region map internal data structures.
185  *
186  * This function is using the L4::Env::env()->rm() service.
187  */
188 L4_CV L4_INLINE void
189 l4re_rm_show_lists(void) L4_NOTHROW;
190 
191 
192 /*
193  * Variants of functions that also take a capability of the region map
194  * service.
195  */
196 
197 
198 /**
199  * \ingroup api_l4re_c_rm
200  * \see L4Re::Rm::reserve_area
201  */
202 L4_CV int
203 l4re_rm_reserve_area_srv(l4_cap_idx_t rm, l4_addr_t *start, unsigned long size,
204                          l4re_rm_flags_t flags, unsigned char align) L4_NOTHROW;
205 
206 /**
207  * \ingroup api_l4re_c_rm
208  * \see L4Re::Rm::free_area
209  */
210 L4_CV int
211 l4re_rm_free_area_srv(l4_cap_idx_t rm, l4_addr_t addr) L4_NOTHROW;
212 
213 /**
214  * \ingroup api_l4re_c_rm
215  * \see L4Re::Rm::attach
216  */
217 L4_CV int
218 l4re_rm_attach_srv(l4_cap_idx_t rm, void **start, unsigned long size,
219                    l4re_rm_flags_t flags, l4re_ds_t mem,
220                    l4re_rm_offset_t offs,
221                    unsigned char align) L4_NOTHROW;
222 
223 
224 /**
225  * \see L4Re::Rm::detach
226  * \ingroup api_l4re_c_rm
227  */
228 L4_CV int
229 l4re_rm_detach_srv(l4_cap_idx_t rm, l4_addr_t addr,
230                    l4re_ds_t *ds, l4_cap_idx_t task) L4_NOTHROW;
231 
232 
233 /**
234  * \see L4Re::Rm::find
235  * \ingroup api_l4re_c_rm
236  */
237 L4_CV int
238 l4re_rm_find_srv(l4_cap_idx_t rm, l4_addr_t *addr,
239                  unsigned long *size, l4re_rm_offset_t *offset,
240                  l4re_rm_flags_t *flags, l4re_ds_t *m) L4_NOTHROW;
241 
242 /**
243  * \brief Dump region map internal data structures.
244  * \ingroup api_l4re_c_rm
245  */
246 L4_CV void
247 l4re_rm_show_lists_srv(l4_cap_idx_t rm) L4_NOTHROW;
248 
249 
250 /********** Implementations ***************************/
251 
252 L4_CV L4_INLINE int
l4re_rm_reserve_area(l4_addr_t * start,unsigned long size,l4re_rm_flags_t flags,unsigned char align)253 l4re_rm_reserve_area(l4_addr_t *start, unsigned long size,
254                      l4re_rm_flags_t flags, unsigned char align) L4_NOTHROW
255 {
256   return l4re_rm_reserve_area_srv(l4re_global_env->rm, start, size,
257                                   flags, align);
258 }
259 
260 L4_CV L4_INLINE int
l4re_rm_free_area(l4_addr_t addr)261 l4re_rm_free_area(l4_addr_t addr) L4_NOTHROW
262 {
263   return l4re_rm_free_area_srv(l4re_global_env->rm, addr);
264 }
265 
266 L4_CV L4_INLINE int
l4re_rm_attach(void ** start,unsigned long size,l4re_rm_flags_t flags,l4re_ds_t mem,l4re_rm_offset_t offs,unsigned char align)267 l4re_rm_attach(void **start, unsigned long size, l4re_rm_flags_t flags,
268                l4re_ds_t mem, l4re_rm_offset_t offs,
269                unsigned char align) L4_NOTHROW
270 {
271   return l4re_rm_attach_srv(l4re_global_env->rm, start, size,
272                             flags, mem, offs, align);
273 }
274 
275 
276 L4_CV L4_INLINE int
l4re_rm_detach(void * addr)277 l4re_rm_detach(void *addr) L4_NOTHROW
278 {
279   return l4re_rm_detach_srv(l4re_global_env->rm,
280                             (l4_addr_t)addr, 0, L4_BASE_TASK_CAP);
281 }
282 
283 L4_CV L4_INLINE int
l4re_rm_detach_unmap(l4_addr_t addr,l4_cap_idx_t task)284 l4re_rm_detach_unmap(l4_addr_t addr, l4_cap_idx_t task) L4_NOTHROW
285 {
286   return l4re_rm_detach_srv(l4re_global_env->rm, addr, 0, task);
287 }
288 
289 L4_CV L4_INLINE int
l4re_rm_detach_ds(void * addr,l4re_ds_t * ds)290 l4re_rm_detach_ds(void *addr, l4re_ds_t *ds) L4_NOTHROW
291 {
292   return l4re_rm_detach_srv(l4re_global_env->rm, (l4_addr_t)addr,
293                             ds, L4_BASE_TASK_CAP);
294 }
295 
296 L4_CV L4_INLINE int
l4re_rm_detach_ds_unmap(void * addr,l4re_ds_t * ds,l4_cap_idx_t task)297 l4re_rm_detach_ds_unmap(void *addr, l4re_ds_t *ds, l4_cap_idx_t task) L4_NOTHROW
298 {
299   return l4re_rm_detach_srv(l4re_global_env->rm, (l4_addr_t)addr,
300                             ds, task);
301 }
302 
303 L4_CV L4_INLINE int
l4re_rm_find(l4_addr_t * addr,unsigned long * size,l4re_rm_offset_t * offset,l4re_rm_flags_t * flags,l4re_ds_t * m)304 l4re_rm_find(l4_addr_t *addr, unsigned long *size,
305              l4re_rm_offset_t *offset,
306              l4re_rm_flags_t *flags, l4re_ds_t *m) L4_NOTHROW
307 {
308   return l4re_rm_find_srv(l4re_global_env->rm, addr, size, offset, flags, m);
309 }
310 
311 L4_CV L4_INLINE void
l4re_rm_show_lists(void)312 l4re_rm_show_lists(void) L4_NOTHROW
313 {
314   l4re_rm_show_lists_srv(l4re_global_env->rm);
315 }
316 
317 EXTERN_C_END
318