]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/test/unit/mapdb_t.cpp
b97d60ca6d93784e7a99b1ab60fcf6213f8e7b8d
[l4.git] / kernel / fiasco / src / test / unit / mapdb_t.cpp
1 IMPLEMENTATION:
2
3 #include <iostream>
4 #include <iomanip>
5 #include <cassert>
6 #include <cstdlib>
7
8 using namespace std;
9
10 #include "mapdb.h"
11
12 IMPLEMENTATION:
13
14 #include "config.h"
15 #include "space.h"
16
17 static Space *s0;
18 static Space *other;
19 static Space *client;
20 static Space *father;
21 static Space *&grandfather = s0;
22 static Space *son;
23 static Space *daughter;
24 static Space *aunt;
25
26 typedef Virt_addr Phys_addr;
27
28 static size_t page_sizes[] =
29 { Config::SUPERPAGE_SHIFT - Config::PAGE_SHIFT, 0 };
30
31 static size_t page_sizes_max = 2;
32
33
34 static void init_spaces()
35 {
36   static Ram_quota rq;
37   L4_fpage utcb_area = L4_fpage::mem(0x1200000, Config::PAGE_SHIFT);
38   s0       = new Space(Space::Default_factory(), &rq, utcb_area);
39   other    = new Space(Space::Default_factory(), &rq, utcb_area);
40   client   = new Space(Space::Default_factory(), &rq, utcb_area);
41   father   = new Space(Space::Default_factory(), &rq, utcb_area);
42   son      = new Space(Space::Default_factory(), &rq, utcb_area);
43   daughter = new Space(Space::Default_factory(), &rq, utcb_area);
44   aunt     = new Space(Space::Default_factory(), &rq, utcb_area);
45 }
46
47 static void print_node(Mapping* node, const Mapdb::Frame& frame)
48 {
49   assert (node);
50
51   size_t shift;
52
53   for (Mapdb::Iterator i(frame, node, Virt_addr(0), Virt_addr(~0)); node;)
54     {
55       for (int d = node->depth(); d != 0; d--)
56         cout << ' ';
57
58       shift = i.shift();
59
60       cout << setbase(16)
61            << "space=0x"  << (unsigned) (node->space())
62            << " vaddr=0x" << (node->page() << shift).value()
63            << " size=0x" << (1UL << shift);
64
65       if (Mapping* p = node->parent())
66         {
67           cout << " parent=0x" << p->space()
68                << " p.vaddr=0x" << (p->page() << shift).value();
69         }
70
71       cout << endl;
72
73       node = i;
74       if (node)
75         {
76           shift = i.shift();
77           ++i;
78         }
79     }
80   cout << endl;
81 }
82
83 void basic()
84 {
85   Mapdb m (s0, Page_number(1U << (32 - Config::SUPERPAGE_SHIFT)), page_sizes, page_sizes_max);
86
87   Mapping *node, *sub, *subsub;
88   Mapdb::Frame frame;
89
90   assert (! m.lookup(other, Mem_space::Addr::create(Config::PAGE_SIZE),
91                      Mem_space::Phys_addr::create(Config::PAGE_SIZE),
92                      &node, &frame));
93
94   cout << "Looking up 4M node at physaddr=0K" << endl;
95   assert (m.lookup (s0,  Mem_space::Addr::create(0),
96                     Mem_space::Phys_addr::create(0),
97                     &node, &frame));
98   print_node (node, frame);
99
100   cout << "Inserting submapping" << endl;
101   sub = m.insert (frame, node, other,
102                   Mem_space::Addr::create(2*Config::PAGE_SIZE),
103                   Mem_space::Phys_addr::create(Config::PAGE_SIZE),
104                   Mem_space::Size::create(Config::PAGE_SIZE));
105   print_node (node, frame);
106
107   m.free (frame);
108
109   //////////////////////////////////////////////////////////////////////
110
111   cout << "Looking up 4M node at physaddr=8M" << endl;
112   assert (m.lookup (s0,
113                     Mem_space::Addr::create(2*Config::SUPERPAGE_SIZE),
114                     Mem_space::Phys_addr::create(2*Config::SUPERPAGE_SIZE),
115                     &node, &frame));
116   print_node (node, frame);
117
118   // XXX broken mapdb: assert (node->size() == Config::SUPERPAGE_SIZE);
119
120   cout << "Inserting submapping" << endl;
121   sub = m.insert (frame, node, other,
122                   Mem_space::Addr::create(4*Config::SUPERPAGE_SIZE),
123                   Mem_space::Phys_addr::create(2*Config::SUPERPAGE_SIZE),
124                   Mem_space::Size::create(Config::SUPERPAGE_SIZE));
125   print_node (node, frame);
126
127   assert (m.shift(frame, sub) == Config::SUPERPAGE_SHIFT- Config::PAGE_SHIFT);
128
129   // Before we can insert new mappings, we must free the tree.
130   m.free (frame);
131
132   cout << "Get that mapping again" << endl;
133   assert (m.lookup (other,
134                     Mem_space::Addr::create(4*Config::SUPERPAGE_SIZE),
135                     Mem_space::Phys_addr::create(2*Config::SUPERPAGE_SIZE),
136                     &sub, &frame));
137   print_node (sub, frame);
138
139   node = sub->parent();
140
141   cout << "Inserting 4K submapping" << endl;
142   subsub = m.insert (frame, sub, client,
143                      Mem_space::Addr::create(15*Config::PAGE_SIZE),
144                      Mem_space::Phys_addr::create(2*Config::SUPERPAGE_SIZE),
145                      Mem_space::Size::create(Config::PAGE_SIZE));
146   print_node (node, frame);
147
148   m.free (frame);
149 }
150
151 static void print_whole_tree(Mapping *node, const Mapdb::Frame& frame)
152 {
153   while(node->parent())
154     node = node->parent();
155   print_node (node, frame);
156 }
157
158
159 void maphole()
160 {
161   Mapdb m(s0, Page_number(1U << (32 - Config::SUPERPAGE_SHIFT)),
162       page_sizes, page_sizes_max);
163
164   Mapping *gf_map, *f_map, *son_map, *daughter_map, *a_map;
165   Mapdb::Frame frame;
166
167   cout << "Looking up 4K node at physaddr=0" << endl;
168   assert (m.lookup (grandfather, Mem_space::Addr::create(0),
169                     Mem_space::Phys_addr::create(0), &gf_map, &frame));
170   print_whole_tree (gf_map, frame);
171
172   cout << "Inserting father mapping" << endl;
173   f_map = m.insert (frame, gf_map, father, Mem_space::Addr::create(0),
174                     Mem_space::Phys_addr::create(0),
175                     Mem_space::Size::create(Config::PAGE_SIZE));
176   print_whole_tree (gf_map, frame);
177   m.free(frame);
178
179
180   cout << "Looking up father at physaddr=0" << endl;
181   assert (m.lookup (father, Mem_space::Addr::create(0),
182                     Mem_space::Phys_addr::create(0), &f_map, &frame));
183   print_whole_tree (f_map, frame);
184
185   cout << "Inserting son mapping" << endl;
186   son_map = m.insert (frame, f_map, son, Mem_space::Addr::create(0),
187                       Mem_space::Phys_addr::create(0),
188                       Mem_space::Size::create(Config::PAGE_SIZE));
189   print_whole_tree (f_map, frame);
190   m.free(frame);
191
192
193   cout << "Looking up father at physaddr=0" << endl;
194   assert (m.lookup (father, Mem_space::Addr::create(0),
195                     Mem_space::Phys_addr::create(0), &f_map, &frame));
196   print_whole_tree (f_map, frame);
197
198   cout << "Inserting daughter mapping" << endl;
199   daughter_map = m.insert (frame, f_map, daughter, Mem_space::Addr::create(0),
200                            Mem_space::Phys_addr::create(0),
201                            Mem_space::Size::create(Config::PAGE_SIZE));
202   print_whole_tree (f_map, frame);
203   m.free(frame);
204
205
206   cout << "Looking up son at physaddr=0" << endl;
207   assert (m.lookup(son, Mem_space::Addr::create(0),
208                    Mem_space::Phys_addr::create(0), &son_map, &frame));
209   f_map = son_map->parent();
210   print_whole_tree (son_map, frame);
211
212   cout << "Son has accident on return from disco" << endl;
213   m.flush(frame, son_map, L4_map_mask::full(),
214           Mem_space::Addr::create(0),
215           Mem_space::Addr::create(Config::PAGE_SIZE));
216   m.free(frame);
217
218   cout << "Lost aunt returns from holidays" << endl;
219   assert (m.lookup (grandfather, Mem_space::Addr::create(0),
220                     Mem_space::Phys_addr::create(0), &gf_map, &frame));
221   print_whole_tree (gf_map, frame);
222
223   cout << "Inserting aunt mapping" << endl;
224   a_map = m.insert (frame, gf_map, aunt, Mem_space::Addr::create(0),
225                     Mem_space::Phys_addr::create(0),
226                     Mem_space::Size::create(Config::PAGE_SIZE));
227   print_whole_tree (gf_map, frame);
228   m.free(frame);
229
230   cout << "Looking up daughter at physaddr=0" << endl;
231   assert (m.lookup(daughter, Mem_space::Addr::create(0),
232                    Mem_space::Phys_addr::create(0), &daughter_map, &frame));
233   print_whole_tree (daughter_map, frame);
234   f_map = daughter_map->parent();
235   cout << "Father of daugther is " << (unsigned)(f_map->space()) << endl;
236
237   assert(f_map->space() == father);
238
239   m.free(frame);
240 }
241
242
243 void flushtest()
244 {
245   Mapdb m(s0, Page_number(1U << (32 - Config::SUPERPAGE_SHIFT)), page_sizes, page_sizes_max);
246
247   Mapping *gf_map, *f_map, *son_map, *a_map;
248   Mapdb::Frame frame;
249
250   cout << "Looking up 4K node at physaddr=0" << endl;
251   assert (m.lookup (grandfather, Virt_addr(0), Phys_addr(0), &gf_map, &frame));
252   print_whole_tree (gf_map, frame);
253
254   cout << "Inserting father mapping" << endl;
255   f_map = m.insert (frame, gf_map, father, Virt_addr(0), Phys_addr(0), Virt_size(Config::PAGE_SIZE));
256   print_whole_tree (gf_map, frame);
257   m.free(frame);
258
259
260   cout << "Looking up father at physaddr=0" << endl;
261   assert (m.lookup (father, Virt_addr(0), Phys_addr(0), &f_map, &frame));
262   print_whole_tree (f_map, frame);
263
264   cout << "Inserting son mapping" << endl;
265   son_map = m.insert (frame, f_map, son, Virt_addr(0), Phys_addr(0), Virt_size(Config::PAGE_SIZE));
266   print_whole_tree (f_map, frame);
267   m.free(frame);
268
269   cout << "Lost aunt returns from holidays" << endl;
270   assert (m.lookup (grandfather, Virt_addr(0), Phys_addr(0), &gf_map, &frame));
271   print_whole_tree (gf_map, frame);
272
273   cout << "Inserting aunt mapping" << endl;
274   a_map = m.insert (frame, gf_map, aunt, Virt_addr(0), Phys_addr(0), Virt_size(Config::PAGE_SIZE));
275   print_whole_tree (gf_map, frame);
276   m.free(frame);
277
278   cout << "Looking up father at physaddr=0" << endl;
279   assert (m.lookup(father, Virt_addr(0), Phys_addr(0), &f_map, &frame));
280   gf_map = f_map->parent();
281   print_whole_tree (gf_map, frame);
282
283   cout << "father is killed by his new love" << endl;
284   m.flush(frame, f_map, L4_map_mask::full(), Virt_addr(0), Virt_addr(Config::PAGE_SIZE));
285   print_whole_tree (gf_map, frame);
286   m.free(frame);
287
288   cout << "Try resurrecting the killed father again" << endl;
289   assert (! m.lookup(father, Virt_addr(0), Phys_addr(0), &f_map, &frame));
290
291   cout << "Resurrection is impossible, as it ought to be." << endl;
292 }
293
294 void multilevel ()
295 {
296   size_t three_page_sizes[] = { 30 - Config::PAGE_SHIFT,
297       22 - Config::PAGE_SHIFT,
298       0};
299   Mapdb m (s0, Page_number(4), three_page_sizes, 3);
300
301   Mapping *node /* , *sub, *subsub */;
302   Mapdb::Frame frame;
303
304   cout << "Looking up 0xd2000000" << endl;
305   assert (m.lookup (s0, Virt_addr(0xd2000000), Phys_addr(0xd2000000), &node, &frame));
306
307   print_node (node, frame);
308 }
309
310 #include "boot_info.h"
311 #include "cpu.h"
312 #include "config.h"
313 #include "kip_init.h"
314 #include "kmem.h"
315 #include "kmem_alloc.h"
316 #include "per_cpu_data_alloc.h"
317 #include "static_init.h"
318 #include "usermode.h"
319 #include "vmem_alloc.h"
320
321 class Timeout;
322
323 DEFINE_PER_CPU Per_cpu<Timeout *> timeslice_timeout;
324 STATIC_INITIALIZER_P(init, STARTUP_INIT_PRIO);
325 STATIC_INITIALIZER_P(init2, POST_CPU_LOCAL_INIT_PRIO);
326
327 static void init()
328 {
329   Usermode::init(0);
330   Boot_info::init();
331   Kip_init::setup_ux();
332   Kmem_alloc::base_init();
333   Kip_init::init();
334   Kmem_alloc::init();
335
336   // Initialize cpu-local data management and run constructors for CPU 0
337   Per_cpu_data::init_ctors();
338   Per_cpu_data_alloc::alloc(0);
339   Per_cpu_data::run_ctors(0);
340
341 }
342
343 static void init2()
344 {
345   Cpu::init_global_features();
346   Config::init();
347   Kmem::init_mmu(Cpu::cpus.cpu(0));
348   printf("ha\n");
349   Vmem_alloc::init();
350 }
351
352 int main()
353 {
354   init_spaces();
355   cout << "Basic test" << endl;
356   basic();
357   cout << "########################################" << endl;
358
359   cout << "Hole test" << endl;
360   maphole();
361   cout << "########################################" << endl;
362
363   cout << "Flush test" << endl;
364   flushtest();
365   cout << "########################################" << endl;
366
367   cout << "Multilevel test" << endl;
368   multilevel();
369   cout << "########################################" << endl;
370
371   cerr << "OK" << endl;
372   return(0);
373 }