]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4con/examples/xf86_stub/emul_l4env.c
Inital import
[l4.git] / l4 / pkg / l4con / examples / xf86_stub / emul_l4env.c
1 /*!
2  * \file   con/examples/xf86_stub/emul_l4rm.c
3  * \brief  L4Env emulation functions to be used for L4Linux programs.
4  *
5  * \date   06/19/2001
6  * \author Jork Loeser <jork.loeser@inf.tu-dresden.de>
7  *
8  * This file contains the rm_* emulation functions, because we cannot run
9  * the region mapper with Linux (yes, we could. Somehow.).
10  *
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)                                   !!!
14  */
15
16 /*
17  * Copyright (c) 2003 by Technische Universität Dresden, Germany
18  *
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:
25  *
26  * The above copyright notice and this permission notice shall be included in
27  * all copies or substantial portions of the Software.
28  *
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.
36  *
37  */
38
39 #ifndef XORG73
40 #include "xf86_ansic.h"
41 #include "xf86_libc.h"
42 #else
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <stdlib.h>
46 #include <sys/mman.h>
47 #endif
48
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>
54
55 /***************************************************************************
56  * l4rm stuff
57  **************************************************************************/
58
59 struct vm_area_struct
60 {
61     void *                addr;
62     l4_size_t             size;
63     l4_offs_t             offs;
64     l4dm_dataspace_t      ds;
65     struct vm_area_struct *next;
66 };
67
68 static int fd = 0;
69 static struct vm_area_struct *vm_areas;
70
71 static struct vm_area_struct *reserve_virtual_area(l4_size_t size)
72 {
73   struct vm_area_struct *vm;
74   void *addr;
75
76   if (!fd && (fd = open("/dev/zero", O_RDONLY)) < 0)
77     return NULL;
78
79   if ((addr = mmap(0, size, PROT_NONE, MAP_SHARED, fd, 0)) == MAP_FAILED)
80     return NULL;
81
82   if (!(vm = malloc(sizeof(struct vm_area_struct))))
83     return NULL;
84
85   vm->addr = addr;
86   vm->size = size;
87
88   /* add new area to vm area list */
89   vm->next = vm_areas;
90   vm_areas = vm;
91
92   /* Until we touch the pages, they are not mapped. And if we touch
93      them, we get a SIGSEGV. */
94   return vm;
95 }
96
97 static void free_virtual_area(struct vm_area_struct *vm)
98 {
99   munmap(vm->addr, vm->size);
100   free(vm);
101 }
102
103 /**
104  * \brief Find area which contains \a addr
105  */
106 static struct vm_area_struct *find_virtual_area(l4_addr_t addr)
107 {
108   struct vm_area_struct * vm;
109
110   vm = vm_areas;
111   while (vm != NULL &&
112          (addr <   (l4_addr_t)vm->addr ||
113           addr >= ((l4_addr_t)vm->addr + vm->size)))
114     vm = vm->next;
115
116   return vm;
117 }
118
119 /**
120  * \brief Find area which contains \a addr and remove from vm area list
121  */
122 static struct vm_area_struct *remove_virtual_area(l4_addr_t addr)
123 {
124   struct vm_area_struct * vm, * tmp;
125
126   vm = vm_areas;
127   tmp = NULL;
128   while (vm != NULL &&
129          (addr <  (l4_addr_t)vm->addr &&
130           addr >= (l4_addr_t)vm->addr + vm->size))
131     {
132       tmp = vm;
133       vm = vm->next;
134     }
135
136   if (vm == NULL)
137     /* nothing found */
138     return NULL;
139
140   /* remove */
141   if (tmp == NULL)
142     /* remove first list element */
143     vm_areas = vm_areas->next;
144   else
145     tmp->next = vm->next;
146
147   return vm;
148 }
149
150 /*!\brief Attach dataspace.
151  *
152  * Find an unused map region and attach dataspace area
153  * (ds_offs, ds_offs + size) to that region.
154  *
155  * We use get_vm_area() to find a portion of free memory. Then, we establish
156  * the mapping by issuing dataspace manager calls.
157  *
158  * \note We ignore the flags.
159  */
160 int
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)
163 {
164   struct vm_area_struct *vm;
165   unsigned off;
166   int err;
167   l4_addr_t a,fpage_addr;
168   l4_size_t fpage_size;
169
170   /* align size */
171   size = l4_round_page(size);
172
173   /* sanity checks */
174   if (l4dm_is_invalid_ds(*ds))
175     return -EINVAL;
176                 
177   if (!(vm = reserve_virtual_area(size)))
178     return -ENOMEM;
179   
180   *addr = (l4_addr_t)vm->addr;
181
182   vm->ds = *ds;
183   vm->offs = ds_offs;
184
185   a = (l4_addr_t)vm->addr;
186   for (off = 0; off < size; off += L4_PAGESIZE)
187     {
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);
190       if (err < 0)
191         {
192           int i;
193           for(i = 0; i < off; i += L4_PAGESIZE)
194             {
195               l4_fpage_unmap(l4_fpage(l4_trunc_page(a + i),
196                                       L4_LOG2_PAGESIZE, 0, 0),
197                              L4_FP_FLUSH_PAGE); 
198             }
199
200           return -ENOMEM;
201         }
202
203       ds_offs+=L4_PAGESIZE;
204     }
205   
206   return 0;
207 }
208
209 /*!\brief Pretend to detach a dataspace from a region.
210  *
211  * Actually, this function flushes the pages and frees the vm-area.
212  */
213 int
214 l4rm_detach(const void * addr)
215 {
216   struct vm_area_struct *vm;
217   int off;
218
219   if (!(vm = remove_virtual_area((l4_addr_t)addr)))
220     return -EINVAL;
221
222   for (off = 0; off < vm->size; off += L4_PAGESIZE)
223     {
224       l4_fpage_unmap(l4_fpage(((l4_addr_t)vm->addr + off) & L4_PAGEMASK,
225                               L4_LOG2_PAGESIZE, 0, 0),
226                      L4_FP_FLUSH_PAGE);
227     }
228
229   free_virtual_area(vm);
230   return 0;
231 }
232
233 /*!\brief Pretend to reserve an area
234  *
235  * This function actually does nothing.
236  *
237  * \note This means, areas are comletely ignored!
238  */
239 int l4rm_do_reserve(l4_addr_t *addr, l4_size_t size, l4_uint32_t flags,
240                     l4_uint32_t *area)
241 {
242   *area = 0;
243   return 0;
244 }
245
246 /**
247  * \brief Lookup VM address
248  */
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)
251 {
252   struct vm_area_struct * vm;
253   l4_addr_t a = (l4_addr_t)addr;
254
255   if (!(vm = find_virtual_area(a)))
256     return -EINVAL;
257
258   *ds       = vm->ds;
259   *offset   = (a - (l4_addr_t)vm->addr) + vm->offs;
260   *map_addr = (l4_addr_t)vm->addr;
261   *map_size = vm->size;
262
263   return L4RM_REGION_DATASPACE;
264 }
265
266 /* more dummies */
267 int 
268 l4rm_init(int have_l4env, l4rm_vm_range_t used[], int num_used)
269 {
270   return 0;
271 }
272
273 void
274 l4rm_service_loop(void)
275 {
276   for (;;);
277 }
278
279 void
280 l4rm_show_region_list(void)
281 {
282 }
283
284 l4_threadid_t
285 l4env_get_default_dsm(void)
286 {
287   return L4_INVALID_ID;
288 }
289
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,...)
292 {
293 }
294
295 int LOG_printf(const char *format, ...);
296 int LOG_printf(const char *format, ...)
297 {
298   return 0;
299 }