3 * \brief Helpful utility functions
7 * Copyright (c) 2009, 2010, 2011, ETH Zurich.
8 * Copyright (c) 2014, HP Labs.
11 * This file is distributed under the terms in the attached LICENSE file.
12 * If you do not find this file, copies can be found by writing to:
13 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
16 #include <barrelfish/barrelfish.h>
19 * \brief Translate a lvaddr_t to genvaddr_t
21 genvaddr_t vspace_lvaddr_to_genvaddr(lvaddr_t lvaddr)
23 struct vspace *vspace = get_current_vspace();
24 return vspace_layout_lvaddr_to_genvaddr(&vspace->layout, lvaddr);
28 * \brief Translate a genvaddr_t to lvaddr_t
30 lvaddr_t vspace_genvaddr_to_lvaddr(genvaddr_t genvaddr)
32 struct vspace *vspace = get_current_vspace();
33 return vspace_layout_genvaddr_to_lvaddr(&vspace->layout, genvaddr);
36 errval_t vspace_unmap(const void *buf)
40 struct vregion *vregion = vspace_get_region(get_current_vspace(), buf);
43 err = vregion_destroy(vregion);
44 if (err_is_fail(err)) {
45 return err_push(err, LIB_ERR_VREGION_DESTROY);
51 /// Map with an alignment constraint
52 errval_t vspace_map_anon_nomalloc(void **retaddr, struct memobj_anon *memobj,
53 struct vregion *vregion, size_t size,
54 size_t *retsize, vregion_flags_t flags,
58 size = ROUND_UP(size, BASE_PAGE_SIZE);
63 // Create a memobj and vregion
64 err1 = memobj_create_anon(memobj, size, 0);
65 if (err_is_fail(err1)) {
66 err1 = err_push(err1, LIB_ERR_MEMOBJ_CREATE_ANON);
69 err1 = vregion_map_aligned(vregion, get_current_vspace(),
70 (struct memobj *)memobj, 0, size,
72 if (err_is_fail(err1)) {
73 err1 = err_push(err1, LIB_ERR_VREGION_MAP);
77 *retaddr = (void*)vspace_genvaddr_to_lvaddr(vregion_get_base_addr(vregion));
82 if (err_no(err1) != LIB_ERR_MEMOBJ_CREATE_ANON) {
83 err2 = memobj_destroy_anon((struct memobj *)memobj);
84 if (err_is_fail(err2)) {
85 DEBUG_ERR(err2, "memobj_destroy_anon failed");
92 * \brief Wrapper for creating and mapping a memory object of type anonymous.
94 * The memory object and vregion are returned so the user can call fill and
95 * pagefault on it to create actual mappings.
97 errval_t vspace_map_anon_aligned(void **retaddr, struct memobj **ret_memobj,
98 struct vregion **ret_vregion, size_t size,
99 size_t *retsize, vregion_flags_t flags,
103 struct memobj_anon *memobj = NULL;
104 struct vregion *vregion = NULL;
107 memobj = malloc(sizeof(struct memobj_anon));
108 assert(memobj != NULL);
110 vregion = malloc(sizeof(struct vregion));
111 assert(vregion != NULL);
113 err = vspace_map_anon_nomalloc(retaddr, memobj, vregion, size,
114 retsize, flags, alignment);
115 if (err_is_fail(err)) {
120 *ret_memobj = (struct memobj *)memobj;
121 *ret_vregion = vregion;
127 * \brief Wrapper for creating and mapping a memory object of type anonymous.
129 * The memory object and vregion are returned so the user can call fill and
130 * pagefault on it to create actual mappings.
132 errval_t vspace_map_anon_attr(void **retaddr, struct memobj **ret_memobj,
133 struct vregion **ret_vregion, size_t size,
134 size_t *retsize, vregion_flags_t flags)
138 struct memobj_anon *memobj = NULL;
139 struct vregion *vregion = NULL;
142 memobj = malloc(sizeof(struct memobj_anon));
143 assert(memobj != NULL);
145 vregion = malloc(sizeof(struct vregion));
146 assert(vregion != NULL);
148 err = vspace_map_anon_nomalloc(retaddr, memobj, vregion, size,
150 if (err_is_fail(err))
156 *ret_memobj = (struct memobj *)memobj;
157 *ret_vregion = vregion;
163 * \brief Wrapper to create and map an anonymous memory object at a fixed address.
165 * The memory object and vregion are returned so the user can call fill and
166 * pagefault on it to create actual mappings.
168 errval_t vspace_map_anon_fixed(genvaddr_t base, size_t size,
169 vregion_flags_t flags,
170 struct vregion **ret_vregion,
171 struct memobj **ret_memobj)
174 struct memobj *memobj = NULL;
175 struct vregion *vregion = NULL;
178 memobj = malloc(sizeof(struct memobj_anon));
180 err1 = LIB_ERR_MALLOC_FAIL;
183 vregion = malloc(sizeof(struct vregion));
185 err1 = LIB_ERR_MALLOC_FAIL;
189 // Create a memobj and vregion
190 err1 = memobj_create_anon((struct memobj_anon*)memobj, size, 0);
191 if (err_is_fail(err1)) {
192 err1 = err_push(err1, LIB_ERR_MEMOBJ_CREATE_ANON);
195 err1 = vregion_map_fixed(vregion, get_current_vspace(), memobj, 0, size,
197 if (err_is_fail(err1)) {
198 err1 = err_push(err1, LIB_ERR_VREGION_MAP);
202 *ret_vregion = vregion;
203 *ret_memobj = memobj;
209 err2 = memobj_destroy_anon(memobj);
210 if (err_is_fail(err2)) {
211 DEBUG_ERR(err2, "memobj_destroy_anon failed");
216 err2 = vregion_destroy(vregion);
217 if (err_is_fail(err2)) {
218 DEBUG_ERR(err2, "vregion_destroy failed");
226 * \brief Wrapper for creating and mapping a memory object of type one frame
228 errval_t vspace_map_one_frame(void **retaddr, size_t size, struct capref frame,
229 struct memobj **retmemobj,
230 struct vregion **retvregion)
232 return vspace_map_one_frame_attr(retaddr, size, frame,
233 VREGION_FLAGS_READ_WRITE, retmemobj,
237 errval_t vspace_map_one_frame_fixed(lvaddr_t addr, size_t size,
239 struct memobj **retmemobj,
240 struct vregion **retvregion)
242 return vspace_map_one_frame_fixed_attr(addr, size, frame,
243 VREGION_FLAGS_READ_WRITE, retmemobj,
247 errval_t vspace_map_one_frame_fixed_attr(lvaddr_t addr, size_t size,
248 struct capref frame, vregion_flags_t flags,
249 struct memobj **retmemobj,
250 struct vregion **retvregion)
253 struct memobj *memobj = NULL;
254 struct vregion *vregion = NULL;
256 size = ROUND_UP(size, BASE_PAGE_SIZE);
259 memobj = malloc(sizeof(struct memobj_one_frame));
261 err1 = LIB_ERR_MALLOC_FAIL;
264 vregion = malloc(sizeof(struct vregion));
266 err1 = LIB_ERR_MALLOC_FAIL;
271 err1 = memobj_create_one_frame((struct memobj_one_frame*)memobj, size, 0);
272 if (err_is_fail(err1)) {
273 err1 = err_push(err1, LIB_ERR_MEMOBJ_CREATE_ONE_FRAME);
277 err1 = memobj->f.fill(memobj, 0, frame, size);
278 if (err_is_fail(err1)) {
279 err1 = err_push(err1, LIB_ERR_MEMOBJ_FILL);
283 err1 = vregion_map_fixed(vregion, get_current_vspace(), memobj, 0, size, addr, flags);
284 if (err_is_fail(err1)) {
285 err1 = err_push(err1, LIB_ERR_VREGION_MAP);
289 err1 = memobj->f.pagefault(memobj, vregion, 0, 0);
290 if (err_is_fail(err1)) {
291 err1 = err_push(err1, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER);
299 *retvregion = vregion;
305 err2 = memobj_destroy_one_frame(memobj);
306 if (err_is_fail(err2)) {
307 DEBUG_ERR(err2, "memobj_destroy_anon failed");
311 err2 = vregion_destroy(vregion);
312 if (err_is_fail(err2)) {
313 DEBUG_ERR(err2, "vregion_destroy failed");
320 * \brief Wrapper for creating and mapping a memory object
321 * of type one frame with specific flags
323 errval_t vspace_map_one_frame_attr(void **retaddr, size_t size,
324 struct capref frame, vregion_flags_t flags,
325 struct memobj **retmemobj,
326 struct vregion **retvregion)
328 return vspace_map_one_frame_attr_aligned(retaddr, size,
329 frame, flags, 0, retmemobj, retvregion);
333 * \brief Wrapper for creating and mapping a memory object
334 * of type one frame with specific flags and a specific alignment
336 errval_t vspace_map_one_frame_attr_aligned(void **retaddr, size_t size,
337 struct capref frame, vregion_flags_t flags,
339 struct memobj **retmemobj,
340 struct vregion **retvregion)
343 struct memobj *memobj = NULL;
344 struct vregion *vregion = NULL;
346 size = ROUND_UP(size, BASE_PAGE_SIZE);
349 memobj = calloc(1, sizeof(struct memobj_one_frame));
351 err1 = LIB_ERR_MALLOC_FAIL;
354 vregion = calloc(1, sizeof(struct vregion));
356 err1 = LIB_ERR_MALLOC_FAIL;
361 err1 = memobj_create_one_frame((struct memobj_one_frame*)memobj, size, 0);
362 if (err_is_fail(err1)) {
363 err1 = err_push(err1, LIB_ERR_MEMOBJ_CREATE_ONE_FRAME);
367 err1 = memobj->f.fill(memobj, 0, frame, size);
368 if (err_is_fail(err1)) {
369 err1 = err_push(err1, LIB_ERR_MEMOBJ_FILL);
373 err1 = vregion_map_aligned(vregion, get_current_vspace(), memobj, 0, size,
375 if (err_is_fail(err1)) {
376 err1 = err_push(err1, LIB_ERR_VREGION_MAP);
380 err1 = memobj->f.pagefault(memobj, vregion, 0, 0);
381 if (err_is_fail(err1)) {
382 err1 = err_push(err1, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER);
386 *retaddr = (void*)vspace_genvaddr_to_lvaddr(vregion_get_base_addr(vregion));
391 *retvregion = vregion;
397 err2 = memobj_destroy_one_frame(memobj);
398 if (err_is_fail(err2)) {
399 DEBUG_ERR(err2, "memobj_destroy_anon failed");
403 err2 = vregion_destroy(vregion);
404 if (err_is_fail(err2)) {
405 DEBUG_ERR(err2, "vregion_destroy failed");
411 errval_t vspace_map_one_frame_one_map(struct memobj_one_frame_one_map *memobj,
412 struct vregion *vregion, size_t size,
417 err = memobj_create_one_frame_one_map(memobj, size, 0);
418 if (err_is_fail(err)) {
419 return err_push(err, LIB_ERR_MEMOBJ_CREATE_ONE_FRAME_ONE_MAP);
421 err = memobj->m.f.fill(&memobj->m, 0, frame, size);
422 if (err_is_fail(err)) {
423 return err_push(err, LIB_ERR_MEMOBJ_FILL);
425 err = vregion_map(vregion, get_current_vspace(), &memobj->m, 0, size,
426 VREGION_FLAGS_READ_WRITE);
427 if (err_is_fail(err)) {
428 return err_push(err, LIB_ERR_VREGION_MAP);
430 err = memobj->m.f.pagefault(&memobj->m, vregion, 0, 0);
431 if (err_is_fail(err)) {
432 return err_push(err, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER);