unsigned long Generic_obj_space<SPACE>::v_delete(Page_number virt, Size size, unsigned long page_attribs = L4_fpage::CRWSD) { (void)size; assert (size.value() == 1); Entry *c; if (Optimize_local && mem_space() == Mem_space::current_mem_space(current_cpu())) { c = cap_virt(virt.value()); if (!c) return 0; Capability cap = Mem_layout::read_special_safe((Capability*)c); if (!cap.valid()) return 0; } else c = get_cap(virt.value()); if (c && c->valid()) { if (page_attribs & L4_fpage::R) c->invalidate(); else c->del_rights(page_attribs & L4_fpage::CWSD); } return 0; }
Obj_space_virt<SPACE>::v_delete(V_pfn virt, Order size, L4_fpage::Rights page_attribs) { (void)size; assert (size == Order(0)); Entry *c; if (Optimize_local && SPACE::mem_space(this) == Mem_space::current_mem_space(current_cpu())) { c = cap_virt(virt); if (!c) return L4_fpage::Rights(0); Capability cap = Mem_layout::read_special_safe((Capability*)c); if (!cap.valid()) return L4_fpage::Rights(0); } else c = get_cap(virt); if (c && c->valid()) { if (page_attribs & L4_fpage::Rights::R()) c->invalidate(); else c->del_rights(page_attribs & L4_fpage::Rights::CWSD()); } return L4_fpage::Rights(0); }
bool Generic_obj_space<SPACE>::v_lookup(Addr const &virt, Phys_addr *phys = 0, Size *size = 0, unsigned *attribs = 0) { if (size) size->set_value(1); Entry *cap; if (Optimize_local && mem_space() == Mem_space::current_mem_space(current_cpu())) cap = cap_virt(virt.value()); else cap = get_cap(virt.value()); if (EXPECT_FALSE(!cap)) { if (size) size->set_value(Caps_per_page); return false; } if (Optimize_local) { Capability c = Mem_layout::read_special_safe((Capability*)cap); if (phys) *phys = c.obj(); if (c.valid() && attribs) *attribs = c.rights(); return c.valid(); } else { Obj::set_entry(virt, cap); if (phys) *phys = cap->obj(); if (cap->valid() && attribs) *attribs = cap->rights(); return cap->valid(); } }
Kobject_iface * Obj_space_virt<SPACE>::lookup_local(Cap_index virt, L4_fpage::Rights *rights) { virt &= Cap_index(~(~0UL << Whole_space)); Capability *c = reinterpret_cast<Capability*>(cap_virt(virt)); Capability cap = Mem_layout::read_special_safe(c); if (rights) *rights = L4_fpage::Rights(cap.rights()); return cap.obj(); }
Kobject_iface * Generic_obj_space<SPACE>::lookup_local(Address virt, unsigned char *rights = 0) { virt &= ~(~0UL << Whole_space); Capability *c = reinterpret_cast<Capability*>(cap_virt(virt)); Capability cap = Mem_layout::read_special_safe(c); if (rights) *rights = cap.rights(); return cap.obj(); }
typename Obj_space_virt<SPACE>::Entry * Obj_space_virt<SPACE>::get_cap(Cap_index index) { Mem_space *ms = SPACE::mem_space(this); Address phys = Address(ms->virt_to_phys((Address)cap_virt(index))); if (EXPECT_FALSE(phys == ~0UL)) return 0; return reinterpret_cast<Entry*>(Mem_layout::phys_to_pmem(phys)); }
typename Generic_obj_space<SPACE>::Entry * Generic_obj_space<SPACE>::alien_lookup(Address index) { Mem_space *ms = mem_space(); Address phys = Address(ms->virt_to_phys((Address)cap_virt(index))); if (EXPECT_FALSE(phys == ~0UL)) return 0; return reinterpret_cast<Entry*>(Mem_layout::phys_to_pmem(phys)); }
typename Obj_space_virt<SPACE>::Capability __attribute__((__flatten__)) Obj_space_virt<SPACE>::lookup(Cap_index virt) { Capability *c; virt &= Cap_index(~(~0UL << Whole_space)); if (SPACE::mem_space(this) == Mem_space::current_mem_space(current_cpu())) c = reinterpret_cast<Capability*>(cap_virt(virt)); else c = get_cap(virt); if (EXPECT_FALSE(!c)) return Capability(0); // void return Mem_layout::read_special_safe(c); }
typename Generic_obj_space<SPACE>::Capability Generic_obj_space<SPACE>::lookup(Address virt) { Capability *c; virt &= ~(~0UL << Whole_space); if (mem_space() == Mem_space::current_mem_space(current_cpu())) c = reinterpret_cast<Capability*>(cap_virt(virt)); else c = get_cap(virt); if (EXPECT_FALSE(!c)) return Capability(0); // void return Mem_layout::read_special_safe(c); }
typename Generic_obj_space<SPACE>::Status Generic_obj_space<SPACE>::v_insert(Phys_addr phys, Addr const &virt, Size size, unsigned char page_attribs) { (void)size; assert (size.value() == 1); Entry *c; if (Optimize_local && mem_space() == Mem_space::current_mem_space(current_cpu())) { c = cap_virt(virt.value()); if (!c) return Insert_err_nomem; Capability cap; if (!Mem_layout::read_special_safe((Capability*)c, cap) && !caps_alloc(virt.value())) return Insert_err_nomem; } else { c = alien_lookup(virt.value()); if (!c && !(c = caps_alloc(virt.value()))) return Insert_err_nomem; Obj::set_entry(virt, c); } if (c->valid()) { if (c->obj() == phys) { if (EXPECT_FALSE(c->rights() == page_attribs)) return Insert_warn_exists; c->add_rights(page_attribs); return Insert_warn_attrib_upgrade; } else return Insert_err_exists; } c->set(phys, page_attribs); return Insert_ok; }
Obj_space_virt<SPACE>::v_insert(Phys_addr phys, V_pfn const &virt, Order size, Attr page_attribs) { (void)size; assert (size == Order(0)); Entry *c; if (Optimize_local && SPACE::mem_space(this) == Mem_space::current_mem_space(current_cpu())) { c = cap_virt(virt); if (!c) return Obj::Insert_err_nomem; Capability cap; if (!Mem_layout::read_special_safe((Capability*)c, cap) && !caps_alloc(virt)) return Obj::Insert_err_nomem; } else { c = get_cap(virt); if (!c && !(c = caps_alloc(virt))) return Obj::Insert_err_nomem; Obj::set_entry(virt, c); } if (c->valid()) { if (c->obj() == phys) { if (EXPECT_FALSE(c->rights() == page_attribs)) return Obj::Insert_warn_exists; c->add_rights(page_attribs); return Obj::Insert_warn_attrib_upgrade; } else return Obj::Insert_err_exists; } c->set(phys, page_attribs); return Obj::Insert_ok; }
/*inline NEEDS["kmem_alloc.h", <cstring>, "ram_quota.h", Obj_space_virt::cap_virt]*/ typename Obj_space_virt<SPACE>::Entry * Obj_space_virt<SPACE>::caps_alloc(Cap_index virt) { Address cv = (Address)cap_virt(virt); void *mem = Kmem_alloc::allocator()->q_unaligned_alloc(SPACE::ram_quota(this), Config::PAGE_SIZE); if (!mem) return 0; Obj::add_cap_page_dbg_info(mem, SPACE::get_space(this), cxx::int_value<Cap_index>(virt)); Mem::memset_mwords(mem, 0, Config::PAGE_SIZE / sizeof(Mword)); Mem_space::Status s; s = SPACE::mem_space(this)->v_insert( Mem_space::Phys_addr(Mem_space::kernel_space()->virt_to_phys((Address)mem)), cxx::mask_lsb(Virt_addr(cv), Mem_space::Page_order(Config::PAGE_SHIFT)), Mem_space::Page_order(Config::PAGE_SHIFT), Mem_space::Attr(L4_fpage::Rights::RW())); //| Mem_space::Page_referenced | Mem_space::Page_dirty); switch (s) { case Mem_space::Insert_ok: break; case Mem_space::Insert_warn_exists: case Mem_space::Insert_warn_attrib_upgrade: assert (false); break; case Mem_space::Insert_err_exists: case Mem_space::Insert_err_nomem: Kmem_alloc::allocator()->q_unaligned_free(SPACE::ram_quota(this), Config::PAGE_SIZE, mem); return 0; }; unsigned long cap = cv & (Config::PAGE_SIZE - 1) | (unsigned long)mem; return reinterpret_cast<Entry*>(cap); }
/*inline NEEDS["mapped_alloc.h", <cstring>, "ram_quota.h", Generic_obj_space::cap_virt]*/ typename Generic_obj_space<SPACE>::Entry * Generic_obj_space<SPACE>::caps_alloc(Address virt) { Address cv = (Address)cap_virt(virt); void *mem = Mapped_allocator::allocator()->q_unaligned_alloc(ram_quota(), Config::PAGE_SIZE); if (!mem) return 0; add_dbg_info(mem, this, virt); Mem::memset_mwords(mem, 0, Config::PAGE_SIZE / sizeof(Mword)); Mem_space::Status s; s = mem_space()->v_insert( Mem_space::Phys_addr::create(Mem_space::kernel_space()->virt_to_phys((Address)mem)), Mem_space::Addr::create(cv).trunc(Mem_space::Size::create(Config::PAGE_SIZE)), Mem_space::Size::create(Config::PAGE_SIZE), Mem_space::Page_cacheable | Mem_space::Page_writable | Mem_space::Page_referenced | Mem_space::Page_dirty); switch (s) { case Insert_ok: case Insert_warn_exists: case Insert_warn_attrib_upgrade: case Insert_err_exists: break; case Insert_err_nomem: Mapped_allocator::allocator()->q_unaligned_free(ram_quota(), Config::PAGE_SIZE, mem); return 0; }; unsigned long cap = cv & (Config::PAGE_SIZE - 1) | (unsigned long)mem; return reinterpret_cast<Entry*>(cap); }
Obj_space_virt<SPACE>::v_lookup(V_pfn const &virt, Phys_addr *phys, Page_order *size, Attr *attribs) { if (size) *size = Order(0); Entry *cap; if (Optimize_local && SPACE::mem_space(this) == Mem_space::current_mem_space(current_cpu())) cap = cap_virt(virt); else cap = get_cap(virt); if (EXPECT_FALSE(!cap)) { if (size) *size = Order(Obj::Caps_per_page_ld2); return false; } if (Optimize_local) { Capability c = Mem_layout::read_special_safe((Capability*)cap); if (phys) *phys = c.obj(); if (c.valid() && attribs) *attribs = Attr(c.rights()); return c.valid(); } else { Obj::set_entry(virt, cap); if (phys) *phys = cap->obj(); if (cap->valid() && attribs) *attribs = Attr(cap->rights()); return cap->valid(); } }