]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/phys_space.cc
update
[l4.git] / l4 / pkg / io / server / src / phys_space.cc
1 /*
2  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *          Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10 #include <l4/sys/kip>
11 #include <l4/re/env>
12
13 #include <cstdio>
14 #include <cstdlib>
15
16 #include "debug.h"
17 #include "cfg.h"
18 #include "phys_space.h"
19
20 void *operator new (size_t sz, cxx::Nothrow const &) throw()
21 { return malloc(sz); }
22
23 Phys_space Phys_space::space;
24
25 Phys_space::Phys_space()
26 {
27   _set.insert(Phys_region(4 << 22, Phys_region::Addr(~0)));
28   //_set.insert(Phys_region(0xd0000000, Phys_region::Addr(~0)));
29  // reserve(Phys_region(0xe0000000, 0xf0000000-1));
30
31   L4::Kip::Mem_desc *md = L4::Kip::Mem_desc::first(l4re_kip());
32   L4::Kip::Mem_desc *mde = md + L4::Kip::Mem_desc::count(l4re_kip());
33
34   for (; md < mde; ++md)
35     {
36       if (md->is_virtual())
37         continue;
38
39       switch (md->type())
40         {
41         case L4::Kip::Mem_desc::Arch:
42         case L4::Kip::Mem_desc::Conventional:
43         case L4::Kip::Mem_desc::Reserved:
44         case L4::Kip::Mem_desc::Dedicated:
45         case L4::Kip::Mem_desc::Shared:
46         case L4::Kip::Mem_desc::Bootloader:
47             {
48               Phys_region re(l4_trunc_page(md->start()),
49                              l4_round_page(md->end())-1);
50               bool r = reserve(re);
51               d_printf(DBG_INFO, "  reserve phys memory space %014lx-%014lx (%s)\n",
52                        md->start(), md->end(), r ? "ok" : "failed");
53               (void)r;
54             }
55           break;
56         default:
57           break;
58         }
59     }
60
61 }
62
63 bool
64 Phys_space::alloc_from(Set::Iterator const &o, Phys_region const &r)
65 {
66   if (r.contains(*o))
67     {
68       _set.remove(*o);
69       return true;
70     }
71
72   if (o->start() >= r.start())
73     {
74       o->set_start(r.end() + 1);
75       return true;
76     }
77
78   if (o->end() <= r.end())
79     {
80       o->set_end(r.start() - 1);
81       return true;
82     }
83
84   Phys_region nr(r.end() + 1, o->end());
85   o->set_end(r.start() - 1);
86   _set.insert(nr);
87   return true;
88 }
89
90 bool
91 Phys_space::reserve(Phys_region const &r)
92 {
93
94   Set::Iterator n;
95   bool res = false;
96   do
97     {
98       n = _set.find(r);
99       if (n == _set.end())
100         return res;
101
102       res = true;
103     }
104   while (alloc_from(n, r));
105
106   return true;
107 }
108
109 bool
110 Phys_space::alloc(Phys_region const &r)
111 {
112
113   Set::Iterator n;
114   n = _set.find(r);
115   if (n == _set.end())
116     return false;
117
118   if (n->contains(r))
119     {
120       reserve(r);
121       return true;
122     }
123
124   return false;
125 }
126
127 Phys_space::Phys_region
128 Phys_space::alloc(Phys_region::Addr sz, Phys_region::Addr align)
129 {
130   for (Set::Iterator i = _set.begin(); i != _set.end(); ++i)
131     {
132       if (i->start() > Phys_region::Addr(0) - sz)
133         continue;
134
135       Phys_region r((i->start() + align) & ~align, 0);
136       r.set_end(r.start() + sz - 1);
137
138       if (i->contains(r))
139         {
140           reserve(r);
141           return r;
142         }
143     }
144
145   return Phys_region();
146 }
147
148 void
149 Phys_space::dump()
150 {
151   printf("unused physical memory space:\n");
152   for (Set::Iterator i = _set.begin(); i != _set.end(); ++i)
153     printf("  [%014lx-%014lx]\n", i->start(), i->end());
154 }