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