5 //--------------------------------------------------------------------------
14 /** Global definition of Io_space for map_util stuff. */
15 typedef Generic_io_space<Space> Io_space;
17 //--------------------------------------------------------------------------
20 #include "mem_space.h"
21 #include "member_offs.h"
22 #include "obj_space.h"
23 #include "spin_lock.h"
25 #include "slab_cache_anon.h"
33 typedef Generic_obj_space<Space> Obj_space;
35 class Space : public Ref_cnt_obj
38 friend class Jdb_space;
42 struct Default_factory
44 /** Create a usual Mem_space object. */
45 template< typename A1 >
46 static void create(Mem_space *v, A1 a1)
47 { new (v) Mem_space(a1); }
49 /** Create a kernel Mem_space object. */
50 template< typename A1, typename A2 >
51 static void create(Mem_space *v, A1 a1, A2 a2)
52 { new (v) Mem_space(a1, a2); }
54 template< typename S >
55 static void create(S *v)
59 /** The interface for Obj_space to get the surrounding Space. */
60 static Space *space(Obj_space const *os)
62 return reinterpret_cast<Space*>(Address(os) - Address(&reinterpret_cast<Space*>(32)->_obj_space) + 32);
66 { // we must use values with the two lest significant bits == 0
75 User<void>::Ptr u_addr;
79 static slab_cache_anon *a;
83 void *operator new (size_t, Ram_quota *q) throw()
84 { return a->q_alloc(q); }
86 void free(Ram_quota *q) throw()
87 { a->q_free(q, this); }
90 T *kern_addr(Smart_ptr<T, Simple_ptr_policy, User_ptr_discr> ua) const
93 return (T*)((A)ua.get() - (A)u_addr.get() + (A)k_addr);
98 template<typename SPACE>
102 char __attribute__((aligned(__alignof__(Mword)))) s[sizeof(SPACE)];
104 template< typename SF >
105 Space_container(SF const &sf)
106 { sf.create(get()); }
108 template< typename SF, typename A1 >
109 Space_container(SF const &sf, A1 a1)
110 { sf.create(get(), a1); }
112 template< typename SF, typename A1, typename A2 >
113 Space_container(SF const &sf, A1 a1, A2 a2)
114 { sf.create(get(), a1, a2); }
120 { return reinterpret_cast<SPACE*>(s); }
122 SPACE const *get() const
123 { return reinterpret_cast<SPACE const*>(s); }
126 typedef Space_container<Mem_space> Mem_space_container;
129 Mem_space_container _mem_space;
130 Obj_space _obj_space;
132 void switchin_ldt() const;
139 //---------------------------------------------------------------------------
144 #include "lock_guard.h"
146 #include "globalconfig.h"
147 #include "l4_types.h"
156 * UTCB area functions.
162 * Get size of UTCB area in bytes.
164 * @return the size of the UTCB area in bytes.
168 Space::utcb_area_size() const
169 { return _ku_mem->size; }
173 Space::kern_utcb_area() const
174 { return (Address)_ku_mem->k_addr; }
177 * Get the start of the UTCB area in the user address-space.
179 * @return the start address of the UTCB area in trhe user address-space.
183 Space::user_utcb_area() const
184 { return (Address)_ku_mem->u_addr.get(); }
190 Space::Ku_mem const *
191 Space::find_ku_mem(User<void>::Ptr p, unsigned size)
193 Address const pa = (Address)p.get();
196 if (EXPECT_FALSE(pa & (sizeof(double) - 1)))
200 if (EXPECT_FALSE(pa + size < pa))
203 for (Ku_mem const *f = _ku_mem; f; f = f->next)
205 Address const a = (Address)f->u_addr.get();
206 if (a <= pa && (a + f->size) >= (pa + size))
219 /** Constructor. Creates a new address space and registers it with
222 * Registration may fail (if a task with the given number already
223 * exists, or if another thread creates an address space for the same
224 * task number concurrently). In this case, the newly-created
225 * address space should be deleted again.
227 * @param number Task number of the new address space
229 PUBLIC template< typename SPACE_FACTORY >
231 Space::Space(SPACE_FACTORY const &sf, Ram_quota *q)
232 : _mem_space(sf, q), _ku_mem(0)
233 #ifdef CONFIG_IO_PROT
239 PROTECTED template<typename SPACE_FACTORY>
240 Space::Space(SPACE_FACTORY const &sf, Ram_quota *q, Mem_space::Dir_type* pdir)
241 : _mem_space(sf, q, pdir)
242 #ifdef CONFIG_IO_PROT
250 Space::ram_quota() const
251 { return _mem_space.get()->ram_quota(); }
257 _mem_space.get()->reset_dirty();
263 Space::switchin_context(Space *from)
265 // XXX: check when activating unbound thread for drq-handling
266 // better solution: set freshly created (unbound) threads to kernel_space
267 // so that we do not have to make the following 'if':
270 _mem_space.get()->switchin_context(from->mem_space());
278 // Mem_space utilities
280 // Return memory space.
283 Space::mem_space() const
284 { return _mem_space.get(); }
290 return _mem_space.get();
295 Space::is_user_memory(Address address, Mword len)
297 return address < Mem_layout::User_max
298 && address < address + len // prevent overflow
299 && address + len <= Mem_layout::User_max;
304 Space::lookup_space(Mem_space** out_space)
306 *out_space = mem_space();
319 Space::lookup_space(Obj_space** out_cap_space)
321 *out_cap_space = obj_space();
325 // ------------------------------------------------------------------------
326 IMPLEMENTATION [!io && !ux]:
328 // Is this task a privileged one?
331 Space::has_io_privileges()