6 #include "obj_space_types.h"
8 template<typename SPACE>
12 typedef Obj::Attr Attr;
13 typedef Obj::Capability Capability;
14 typedef Obj::Entry Entry;
15 typedef Kobject_iface *Phys_addr;
17 typedef Obj::Cap_addr V_pfn;
18 typedef Cap_diff V_pfc;
19 typedef Order Page_order;
21 bool v_lookup(V_pfn const &virt, Phys_addr *phys,
22 Page_order *size, Attr *attribs);
24 L4_fpage::Rights v_delete(V_pfn virt, Order size,
25 L4_fpage::Rights page_attribs);
26 Obj::Insert_result v_insert(Phys_addr phys, V_pfn const &virt, Order size,
29 Capability lookup(Cap_index virt);
34 // do not use the virtually mapped cap table in
35 // v_lookup and v_insert, because the map logic needs the kernel
36 // address for link pointers in the map-nodes and these addresses must
37 // be valid in all address spaces.
41 Map_max_address = 1UL << 20, /* 20bit obj index */
54 #include "kmem_alloc.h"
55 #include "mem_layout.h"
57 PRIVATE template< typename SPACE >
58 static inline NEEDS["mem_layout.h"]
59 typename Obj_space_virt<SPACE>::Entry *
60 Obj_space_virt<SPACE>::cap_virt(Cap_index index)
61 { return reinterpret_cast<Entry*>(Mem_layout::Caps_start) + cxx::int_value<Cap_index>(index); }
65 PRIVATE template< typename SPACE >
66 inline NEEDS["mem_space.h", "mem_layout.h", Obj_space_virt::cap_virt]
67 typename Obj_space_virt<SPACE>::Entry *
68 Obj_space_virt<SPACE>::get_cap(Cap_index index)
70 Mem_space *ms = SPACE::mem_space(this);
72 Address phys = Address(ms->virt_to_phys((Address)cap_virt(index)));
73 if (EXPECT_FALSE(phys == ~0UL))
76 return reinterpret_cast<Entry*>(Mem_layout::phys_to_pmem(phys));
79 PRIVATE template< typename SPACE >
80 /*inline NEEDS["kmem_alloc.h", <cstring>, "ram_quota.h",
81 Obj_space_virt::cap_virt]*/
82 typename Obj_space_virt<SPACE>::Entry *
83 Obj_space_virt<SPACE>::caps_alloc(Cap_index virt)
85 Address cv = (Address)cap_virt(virt);
86 void *mem = Kmem_alloc::allocator()->q_unaligned_alloc(SPACE::ram_quota(this), Config::PAGE_SIZE);
91 Obj::add_cap_page_dbg_info(mem, SPACE::get_space(this), cxx::int_value<Cap_index>(virt));
93 Mem::memset_mwords(mem, 0, Config::PAGE_SIZE / sizeof(Mword));
96 s = SPACE::mem_space(this)->v_insert(
97 Mem_space::Phys_addr(Mem_space::kernel_space()->virt_to_phys((Address)mem)),
98 cxx::mask_lsb(Virt_addr(cv), Mem_space::Page_order(Config::PAGE_SHIFT)),
99 Mem_space::Page_order(Config::PAGE_SHIFT),
100 Mem_space::Attr(L4_fpage::Rights::RW()));
101 //| Mem_space::Page_referenced | Mem_space::Page_dirty);
105 case Mem_space::Insert_ok:
107 case Mem_space::Insert_warn_exists:
108 case Mem_space::Insert_warn_attrib_upgrade:
111 case Mem_space::Insert_err_exists:
112 case Mem_space::Insert_err_nomem:
113 Kmem_alloc::allocator()->q_unaligned_free(SPACE::ram_quota(this),
114 Config::PAGE_SIZE, mem);
118 unsigned long cap = cv & (Config::PAGE_SIZE - 1) | (unsigned long)mem;
120 return reinterpret_cast<Entry*>(cap);
123 PROTECTED template< typename SPACE >
125 Obj_space_virt<SPACE>::caps_free()
127 Mem_space *ms = SPACE::mem_space(this);
128 if (EXPECT_FALSE(!ms || !ms->dir()))
131 Kmem_alloc *a = Kmem_alloc::allocator();
132 for (Cap_index i = Cap_index(0); i < obj_map_max_address();
133 i += Cap_diff(Obj::Caps_per_page))
135 Entry *c = get_cap(i);
139 Address cp = Address(ms->virt_to_phys(Address(c)));
140 assert_kdb (cp != ~0UL);
141 void *cv = (void*)Mem_layout::phys_to_pmem(cp);
142 Obj::remove_cap_page_dbg_info(cv);
144 a->q_unaligned_free(SPACE::ram_quota(this), Config::PAGE_SIZE, cv);
146 ms->dir()->destroy(Virt_addr(Mem_layout::Caps_start),
147 Virt_addr(Mem_layout::Caps_end-1),
150 Kmem_alloc::q_allocator(SPACE::ram_quota(this)));
154 // Utilities for map<Obj_space_virt> and unmap<Obj_space_virt>
157 IMPLEMENT template< typename SPACE >
158 inline NEEDS[Obj_space_virt::cap_virt, Obj_space_virt::get_cap]
159 bool __attribute__((__flatten__))
160 Obj_space_virt<SPACE>::v_lookup(V_pfn const &virt, Phys_addr *phys,
161 Page_order *size, Attr *attribs)
163 if (size) *size = Order(0);
167 && SPACE::mem_space(this) == Mem_space::current_mem_space(current_cpu()))
168 cap = cap_virt(virt);
172 if (EXPECT_FALSE(!cap))
174 if (size) *size = Order(Obj::Caps_per_page_ld2);
180 Capability c = Mem_layout::read_special_safe((Capability*)cap);
182 if (phys) *phys = c.obj();
183 if (c.valid() && attribs)
184 *attribs = Attr(c.rights());
189 Obj::set_entry(virt, cap);
190 if (phys) *phys = cap->obj();
191 if (cap->valid() && attribs)
192 *attribs = Attr(cap->rights());
197 IMPLEMENT template< typename SPACE >
198 inline NEEDS [Obj_space_virt::cap_virt, Obj_space_virt::get_cap]
199 typename Obj_space_virt<SPACE>::Capability __attribute__((__flatten__))
200 Obj_space_virt<SPACE>::lookup(Cap_index virt)
203 virt &= Cap_index(~(~0UL << Whole_space));
205 if (SPACE::mem_space(this) == Mem_space::current_mem_space(current_cpu()))
206 c = reinterpret_cast<Capability*>(cap_virt(virt));
210 if (EXPECT_FALSE(!c))
211 return Capability(0); // void
213 return Mem_layout::read_special_safe(c);
216 PUBLIC template< typename SPACE >
217 inline NEEDS [Obj_space_virt::cap_virt]
219 Obj_space_virt<SPACE>::lookup_local(Cap_index virt, L4_fpage::Rights *rights)
221 virt &= Cap_index(~(~0UL << Whole_space));
222 Capability *c = reinterpret_cast<Capability*>(cap_virt(virt));
223 Capability cap = Mem_layout::read_special_safe(c);
224 if (rights) *rights = L4_fpage::Rights(cap.rights());
229 IMPLEMENT template< typename SPACE >
230 inline NEEDS[<cassert>, Obj_space_virt::cap_virt, Obj_space_virt::get_cap]
231 L4_fpage::Rights __attribute__((__flatten__))
232 Obj_space_virt<SPACE>::v_delete(V_pfn virt, Order size,
233 L4_fpage::Rights page_attribs)
236 assert (size == Order(0));
240 && SPACE::mem_space(this) == Mem_space::current_mem_space(current_cpu()))
244 return L4_fpage::Rights(0);
246 Capability cap = Mem_layout::read_special_safe((Capability*)c);
248 return L4_fpage::Rights(0);
255 if (page_attribs & L4_fpage::Rights::R())
258 c->del_rights(page_attribs & L4_fpage::Rights::CWSD());
261 return L4_fpage::Rights(0);
264 IMPLEMENT template< typename SPACE >
265 inline NEEDS[Obj_space_virt::cap_virt, Obj_space_virt::caps_alloc,
266 Obj_space_virt::get_cap, "kdb_ke.h"]
267 typename Obj::Insert_result __attribute__((__flatten__))
268 Obj_space_virt<SPACE>::v_insert(Phys_addr phys, V_pfn const &virt, Order size,
272 assert (size == Order(0));
277 && SPACE::mem_space(this) == Mem_space::current_mem_space(current_cpu()))
281 return Obj::Insert_err_nomem;
284 if (!Mem_layout::read_special_safe((Capability*)c, cap)
285 && !caps_alloc(virt))
286 return Obj::Insert_err_nomem;
291 if (!c && !(c = caps_alloc(virt)))
292 return Obj::Insert_err_nomem;
293 Obj::set_entry(virt, c);
298 if (c->obj() == phys)
300 if (EXPECT_FALSE(c->rights() == page_attribs))
301 return Obj::Insert_warn_exists;
303 c->add_rights(page_attribs);
304 return Obj::Insert_warn_attrib_upgrade;
307 return Obj::Insert_err_exists;
310 c->set(phys, page_attribs);
311 return Obj::Insert_ok;
315 PUBLIC template< typename SPACE >
317 typename Obj_space_virt<SPACE>::V_pfn
318 Obj_space_virt<SPACE>::obj_map_max_address() const
322 r = (Mem_layout::Caps_end - Mem_layout::Caps_start) / sizeof(Entry);
323 if (Map_max_address < r)
329 // ------------------------------------------------------------------------------
330 IMPLEMENTATION [debug]:
332 PUBLIC template< typename SPACE >
333 typename Obj_space_virt<SPACE>::Entry *
334 Obj_space_virt<SPACE>::jdb_lookup_cap(Cap_index index)
335 { return get_cap(index); }