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.
14 #include <l4/sys/compiler.h>
15 #include <l4/sys/l4int.h>
19 /** Region in memory. */
23 enum Type { No_mem, Kernel, Sigma0, Boot, Root, Arch, Ram, Info };
25 /** Basic noop constructor, to be able to have array without ini code */
28 /** Create an invalid region. */
29 Region(Type) : _begin(0), _end(0) {}
31 /** Create a 1byte region at begin, basically for lookups */
32 Region(unsigned long long begin)
33 : _begin(begin), _end(begin), _name(0), _t(No_mem), _s(0)
36 /** Create a 1byte region for address \a ptr.
37 * @param ptr the start address for the 1byte region.
39 Region(void const *ptr)
40 : _begin((l4_addr_t)ptr), _end((l4_addr_t)ptr), _name(0), _t(No_mem), _s(0)
43 /** Create a fully fledged region.
44 * @param begin The start address.
45 * @param end The address of the last byte in the region.
46 * @param name The name for the region (usually the binary name).
47 * @param t The type of the region.
48 * @param sub The subtype of the region.
50 Region(unsigned long long begin, unsigned long long end,
51 char const *name = 0, Type t = No_mem, short sub = 0)
52 : _begin(begin), _end(end), _name(name), _t(t), _s(sub)
57 * @param other a region to copy the name, the type, and the sub_type from
58 * @param begin the start address of the new region
59 * @param end the end address (inclusive) of the new region
61 Region(Region const &other, unsigned long long begin, unsigned long long end)
62 : _begin(begin), _end(end), _name(other._name), _t(other._t), _s(other._s)
67 * @param begin The start address.
68 * @param end The address of the first byte after the region.
69 * @param name The name for the region (usually the binary name).
70 * @param t The type of the region.
71 * @param sub The subtype of the region.
73 static Region n(unsigned long long begin,
74 unsigned long long end, char const *name = 0,
75 Type t = No_mem, short sub = 0)
76 { return Region(begin, end - 1, name, t, sub); }
79 * Create a region (using start and end pointers)
80 * @param begin start address
81 * @param end the address of the last byte in the region
82 * @param name The name of the region
83 * @param t the type of the region
84 * @param sub the subtype of the region
86 static Region n(void const *begin,
87 void const *end, char const *name = 0,
88 Type t = No_mem, short sub = 0)
89 { return Region((l4_addr_t)begin, (l4_addr_t)end - 1, name, t, sub); }
92 * Create a region from start and size.
93 * @param begin the start address of the region
94 * @param size the size of the region in bytes
95 * @param name the name of the region
96 * @param t the type of the region
97 * @param sub the subtype of the region
99 static Region start_size(unsigned long long begin, unsigned long size,
100 char const *name = 0, Type t = No_mem,
102 { return Region(begin, begin + size - 1, name, t, sub); }
105 * Create a region for the given object.
106 * @param begin a pointer to the object that shall be covered
107 * (the size of the region will be sizeof(T))
108 * @param name the name of the region
109 * @param t the type of theregion
110 * @param sub the subtype of the region
112 template< typename T >
113 static Region from_ptr(T const *begin, char const *name = 0,
114 Type t = No_mem, short sub = 0)
115 { return Region::start_size((l4_addr_t)begin, sizeof(T), name, t, sub); }
118 * Create a region for an array of objects.
119 * @param begin pointer to the first element of the array
120 * @param size the number of elements in the array (the size of the
121 * whole region will be size * sizeof(T))
122 * @param name the name of the region
123 * @param t the type of the region
124 * @param sub the subtype of the region
126 template< typename T >
127 static Region array(T const *begin, unsigned long size, char const *name = 0,
128 Type t = No_mem, short sub = 0)
130 return Region::start_size((l4_addr_t)begin, sizeof(T) * size,
134 /** Get the start address. */
135 unsigned long long begin() const { return _begin; }
136 /** Get the address of the last byte. */
137 unsigned long long end() const { return _end; }
138 /** Set the start address. */
139 void begin(unsigned long long b) { _begin = b; }
140 /** Set the address of the last byte. */
141 void end(unsigned long long e) { _end = e; }
142 /** Get the name of the region. */
143 char const *name() const { return _name; }
144 /** Get size of the region */
145 unsigned long long size() const { return _end - _begin + 1; }
146 /** Set the name of the region. */
147 void name(char const *name) { _name = name; }
148 /** Get the type of the region. */
149 Type type() const { return (Type)(_t); }
150 /** Get the subtype of the region. */
151 short sub_type() const { return _s; }
152 /** Set the subtype of the region. */
153 void sub_type(short s) { _s = s; }
155 /** Print the region [begin; end] */
158 /** Print the region verbose (with name and type). */
161 /** Compare two regions. */
162 bool operator < (Region const &o) const
163 { return end() < o.begin(); }
165 /** Check for an overlap. */
166 bool overlaps(Region const &o) const
167 { return !(*this < o) && !(o < *this); }
169 /** Test if o is a sub-region of ourselves. */
170 bool contains(Region const &o) const
171 { return begin() <= o.begin() && end() >= o.end(); }
173 /** Calculate the intersection. */
174 Region intersect(Region const &o) const
177 return Region(No_mem);
179 return Region(begin() > o.begin() ? begin() : o.begin(),
180 end() < o.end() ? end() : o.end(),
181 name(), type(), sub_type());
184 /** Check if the region is invalid */
185 bool invalid() const { return begin()==0 && end()==0; }
188 unsigned long long _begin, _end;
194 /** List of memory regions, based on an fixed size array. */
199 * Initialize the region list, using the array of given size
202 void init(Region *store, unsigned size,
204 unsigned long long max_combined_size = ~0ULL,
205 unsigned long long address_limit = ~0ULL)
210 _max_combined_size = max_combined_size;
211 _address_limit = address_limit;
215 /** Helper template for array parameters
217 * This helper allows to access the type and the size of compile-time
218 * bound arrays. In particular used as parameters.
220 template< typename T >
221 struct Array_type_helper;
223 template< typename T, unsigned SZ >
224 struct Array_type_helper<T[SZ]> {
230 * Initialize the region list, using a region array as store
232 * @param store the array for the regoion backing store.
233 * @param name the name of the region list for output
234 * @param max_combined_size max sum of bytes in this list
235 * @param address_limit maximum allowed address in this list
237 template<typename STORE>
238 void init(STORE &store,
240 unsigned long long max_combined_size = ~0ULL,
241 unsigned long long address_limit = ~0ULL)
243 init(store, Array_type_helper<STORE>::size, name,
244 max_combined_size, address_limit);
247 /** Search for a region that overlaps o. */
248 Region *find(Region const &o) const;
250 /** Search for the region that contains o. */
251 Region *contains(Region const &o);
254 * Search for a memory region not overlapping any known region,
257 unsigned long long find_free(Region const &search,
258 unsigned long long size, unsigned align) const;
261 * Search for a memory region not overlapping any know region, starting
262 * from the end of the search region.
264 unsigned long long find_free_rev(Region const &search, unsigned long long _size,
265 unsigned align) const;
267 * Add a new region, with a upper limit check and verboseness.
269 void add(Region const &r, bool may_overlap = false);
271 bool sub(Region const &r);
273 /** Dump the whole region list. */
276 /** Get the begin() iterator. */
277 Region *begin() const { return _reg; }
278 /** Get the end() iterator. */
279 Region *end() const { return _end; }
281 /** Remove the region given by the iterator r. */
282 Region *remove(Region *r);
284 /** Sort the region list (does bubble sort). */
287 /** Optimize the region list.
288 * Basically merges all regions with the same type, subtype, and name
289 * that have a begin and end address on the same memory page.
299 unsigned long long _max_combined_size;
300 unsigned long long _address_limit;
301 unsigned long long _combined_size;
304 void swap(Region *a, Region *b);
307 * Add a new memory region to the list. The new region must not overlap
310 void add_nolimitcheck(Region const &r, bool may_overlap = false);