2 * \file con/examples/xf86_stub/emul_l4rm.c
3 * \brief L4Env emulation functions to be used for L4Linux programs.
6 * \author Jork Loeser <jork.loeser@inf.tu-dresden.de>
8 * This file contains the rm_* emulation functions, because we cannot run
9 * the region mapper with Linux (yes, we could. Somehow.).
11 * !!! We must _not_ use -ll4env-l4x.p here since we need a version !!!
12 * !!! where system calls are wrapped through X (mmap => xf86mmap; !!!
13 * !!! see CPPFLAGS_emul_l4env.c) !!!
17 * Copyright (c) 2003 by Technische Universität Dresden, Germany
19 * Permission is hereby granted, free of charge, to any person obtaining a
20 * copy of this software and associated documentation files (the "Software"),
21 * to deal in the Software without restriction, including without limitation
22 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
23 * and/or sell copies of the Software, and to permit persons to whom the
24 * Software is furnished to do so, subject to the following conditions:
26 * The above copyright notice and this permission notice shall be included in
27 * all copies or substantial portions of the Software.
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
32 * TECHNISCHE UNIVERSITÄT DRESDEN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
34 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35 * DEALINGS IN THE SOFTWARE.
40 #include "xf86_ansic.h"
41 #include "xf86_libc.h"
49 #include <l4/sys/syscalls.h>
50 #include <l4/sys/consts.h>
51 #include <l4/l4rm/l4rm.h>
52 #include <l4/dm_mem/dm_mem.h>
53 #include <l4/env/env.h>
55 /***************************************************************************
57 **************************************************************************/
65 struct vm_area_struct *next;
69 static struct vm_area_struct *vm_areas;
71 static struct vm_area_struct *reserve_virtual_area(l4_size_t size)
73 struct vm_area_struct *vm;
76 if (!fd && (fd = open("/dev/zero", O_RDONLY)) < 0)
79 if ((addr = mmap(0, size, PROT_NONE, MAP_SHARED, fd, 0)) == MAP_FAILED)
82 if (!(vm = malloc(sizeof(struct vm_area_struct))))
88 /* add new area to vm area list */
92 /* Until we touch the pages, they are not mapped. And if we touch
93 them, we get a SIGSEGV. */
97 static void free_virtual_area(struct vm_area_struct *vm)
99 munmap(vm->addr, vm->size);
104 * \brief Find area which contains \a addr
106 static struct vm_area_struct *find_virtual_area(l4_addr_t addr)
108 struct vm_area_struct * vm;
112 (addr < (l4_addr_t)vm->addr ||
113 addr >= ((l4_addr_t)vm->addr + vm->size)))
120 * \brief Find area which contains \a addr and remove from vm area list
122 static struct vm_area_struct *remove_virtual_area(l4_addr_t addr)
124 struct vm_area_struct * vm, * tmp;
129 (addr < (l4_addr_t)vm->addr &&
130 addr >= (l4_addr_t)vm->addr + vm->size))
142 /* remove first list element */
143 vm_areas = vm_areas->next;
145 tmp->next = vm->next;
150 /*!\brief Attach dataspace.
152 * Find an unused map region and attach dataspace area
153 * (ds_offs, ds_offs + size) to that region.
155 * We use get_vm_area() to find a portion of free memory. Then, we establish
156 * the mapping by issuing dataspace manager calls.
158 * \note We ignore the flags.
161 l4rm_do_attach(const l4dm_dataspace_t * ds, l4_uint32_t area, l4_addr_t * addr,
162 l4_size_t size, l4_offs_t ds_offs, l4_uint32_t flags)
164 struct vm_area_struct *vm;
167 l4_addr_t a,fpage_addr;
168 l4_size_t fpage_size;
171 size = l4_round_page(size);
174 if (l4dm_is_invalid_ds(*ds))
177 if (!(vm = reserve_virtual_area(size)))
180 *addr = (l4_addr_t)vm->addr;
185 a = (l4_addr_t)vm->addr;
186 for (off = 0; off < size; off += L4_PAGESIZE)
188 err = l4dm_map_pages(ds,ds_offs, L4_PAGESIZE, l4_trunc_page(a + off),
189 L4_LOG2_PAGESIZE,0,L4DM_RW,&fpage_addr,&fpage_size);
193 for(i = 0; i < off; i += L4_PAGESIZE)
195 l4_fpage_unmap(l4_fpage(l4_trunc_page(a + i),
196 L4_LOG2_PAGESIZE, 0, 0),
203 ds_offs+=L4_PAGESIZE;
209 /*!\brief Pretend to detach a dataspace from a region.
211 * Actually, this function flushes the pages and frees the vm-area.
214 l4rm_detach(const void * addr)
216 struct vm_area_struct *vm;
219 if (!(vm = remove_virtual_area((l4_addr_t)addr)))
222 for (off = 0; off < vm->size; off += L4_PAGESIZE)
224 l4_fpage_unmap(l4_fpage(((l4_addr_t)vm->addr + off) & L4_PAGEMASK,
225 L4_LOG2_PAGESIZE, 0, 0),
229 free_virtual_area(vm);
233 /*!\brief Pretend to reserve an area
235 * This function actually does nothing.
237 * \note This means, areas are comletely ignored!
239 int l4rm_do_reserve(l4_addr_t *addr, l4_size_t size, l4_uint32_t flags,
247 * \brief Lookup VM address
249 int l4rm_lookup(const void * addr, l4_addr_t * map_addr, l4_size_t * map_size,
250 l4dm_dataspace_t * ds, l4_offs_t * offset, l4_threadid_t * pager)
252 struct vm_area_struct * vm;
253 l4_addr_t a = (l4_addr_t)addr;
255 if (!(vm = find_virtual_area(a)))
259 *offset = (a - (l4_addr_t)vm->addr) + vm->offs;
260 *map_addr = (l4_addr_t)vm->addr;
261 *map_size = vm->size;
263 return L4RM_REGION_DATASPACE;
268 l4rm_init(int have_l4env, l4rm_vm_range_t used[], int num_used)
274 l4rm_service_loop(void)
280 l4rm_show_region_list(void)
285 l4env_get_default_dsm(void)
287 return L4_INVALID_ID;
290 void LOG_logL(const char*file, int line, const char*function, const char*format,...);
291 void LOG_logL(const char*file, int line, const char*function, const char*format,...)
295 int LOG_printf(const char *format, ...);
296 int LOG_printf(const char *format, ...)