2 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>,
4 * Frank Mehnert <fm3@os.inf.tu-dresden.de>
5 * economic rights: Technische Universität Dresden (Germany)
7 * This file is part of TUD:OS and distributed under the terms of the
8 * GNU General Public License 2.
9 * Please see the COPYING-GPL-2 file for details.
16 #include <l4/util/l4_macros.h>
22 Region_list::find_free(Region const &search, unsigned long long _size,
25 unsigned long long start = search.begin();
26 unsigned long long end = search.end();
29 start = (start + (1ULL << align) -1) & ~((1ULL << align)-1);
31 if (start + _size - 1 > end)
35 printf("try start %p\n", (void *)start);
37 Region *z = find(Region::start_size(start, _size));
46 Region_list::find_free_rev(Region const &search, unsigned long long _size,
49 unsigned long long start = search.begin();
50 unsigned long long end = search.end();
54 end &= ~((1ULL << align)-1);
60 printf("try start %p\n", (void *)end);
62 Region *z = find(Region::start_size(end, _size));
71 Region_list::add_nolimitcheck(Region const ®ion, bool may_overlap)
75 /* Do not add empty regions */
76 if (region.begin() == region.end())
81 // try to merge adjacent regions to gain space
85 panic("Bootstrap: %s: Region overflow\n", __func__);
88 if (!may_overlap && (r = find(region)))
90 printf(" New region for list %s:\t", _name);
92 printf(" overlaps with: \t");
96 panic("region overlap");
101 _combined_size += region.size();
105 Region_list::add(Region const ®ion, bool may_overlap)
111 printf(" WARNING: trying to add invalid region to %s list.\n", _name);
115 if (mem.begin() > _address_limit)
117 printf(" Dropping '%s' region ", _name);
119 printf(" due to %lld MB address limit\n", _address_limit >> 20);
123 if (mem.end() >= _address_limit)
125 printf(" Limiting '%s' region ", _name);
127 mem.end(_address_limit - 1);
130 printf(" due to %lld MB address limit\n", _address_limit >> 20);
134 if (_combined_size >= _max_combined_size)
136 printf(" Dropping '%s' region ", _name);
138 printf(" due to %lld MB size limit\n", _max_combined_size >> 20);
142 if (_combined_size + mem.size() > _max_combined_size)
144 printf(" Limiting '%s' region ", _name);
146 mem.end(mem.begin() + _max_combined_size - _combined_size - 1);
149 printf(" due to %lld MB size limit\n", _max_combined_size >> 20);
152 add_nolimitcheck(mem, may_overlap);
156 Region_list::find(Region const &o) const
158 for (Region *c = _reg; c < _end; ++c)
166 Region_list::contains(Region const &o)
168 for (Region *c = _reg; c < _end; ++c)
176 Region::print() const
178 printf(" [%9llx, %9llx] {%9llx}", begin(), end(), size());
182 Region::vprint() const
184 static char const *types[] = {"Gap ", "Kern ", "Sigma0",
185 "Boot ", "Root ", "Arch ", "Ram ",
189 printf(" %s ", types[type()]);
193 printf("%s", name() + 1);
195 print_module_name(name(), "");
205 unsigned long long min, mark = 0;
207 printf("Regions of list '%s'\n", _name);
208 for (i = _reg; i < _end; ++i)
211 Region const *min_idx = 0;
212 for (j = _reg; j < _end; ++j)
213 if (j->begin() < min && j->begin() >= mark)
224 mark = min_idx->begin() + 1;
229 Region_list::swap(Region *a, Region *b)
231 Region t = *a; *a = *b; *b = t;
237 if (end() - begin() < 2)
241 Region *e = end() - 1;
246 for (Region *c = begin(); c < e; ++c)
260 Region_list::remove(Region *r)
262 memmove(r, r+1, (end() - r - 1)*sizeof(Region));
268 Region_list::optimize()
278 if (n->type() == c->type() && n->sub_type() == c->sub_type()
279 && n->name() == c->name() &&
280 l4_round_page(c->end()) >= l4_trunc_page(n->begin()))
291 Region_list::sub(Region const &r)
293 Region *c = contains(r);
297 if (c->begin() == r.begin() && c->end() == r.end())
303 if (c->begin() == r.begin())
305 c->begin(r.end() + 1);
309 if (c->end() == r.end())
311 c->end(r.begin() - 1);
316 tail.begin(r.end() + 1);
317 c->end(r.begin() - 1);