/* * \brief RPC capability factory * \author Norman Feske * \date 2016-01-19 */ /* * Copyright (C) 2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ /* core-local includes */ #include #include using namespace Genode; Native_capability Rpc_cap_factory::alloc(Native_capability ep, addr_t entry, addr_t mtd) { addr_t pt_sel = cap_map()->insert(); addr_t pd_sel = Platform_pd::pd_core_sel(); addr_t ec_sel = ep.local_name(); using namespace Nova; Lock::Guard guard(_lock); /* create cap object */ Cap_object * pt_cap = new (&_slab) Cap_object(pt_sel); if (!pt_cap) return Native_capability::invalid_cap(); _list.insert(pt_cap); /* create portal */ uint8_t const res = create_pt(pt_sel, pd_sel, ec_sel, Mtd(mtd), entry); if (res == NOVA_OK) return Native_capability(pt_sel); PERR("cap_session - cap=%lx:%lx addr=%lx mtd=%lx xpt=%lx res=%u", ec_sel, ep.local_name(), entry, mtd, pt_sel, res); _list.remove(pt_cap); destroy(&_slab, pt_cap); /* cleanup unused selectors */ cap_map()->remove(pt_sel, 0, false); return Native_capability::invalid_cap(); } void Rpc_cap_factory::free(Native_capability cap) { if (!cap.valid()) return; Lock::Guard guard(_lock); for (Cap_object *obj = _list.first(); obj ; obj = obj->next()) { if (cap.local_name() == obj->_cap_sel) { Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0)); cap_map()->remove(obj->_cap_sel, 0, false); _list.remove(obj); destroy(&_slab, obj); return; } } PDBG("invalid cap object"); } Rpc_cap_factory::Rpc_cap_factory(Allocator &md_alloc) : _slab(&md_alloc) { } Rpc_cap_factory::~Rpc_cap_factory() { Lock::Guard guard(_lock); for (Cap_object *obj; (obj = _list.first()); ) { Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0)); cap_map()->remove(obj->_cap_sel, 0, false); _list.remove(obj); destroy(&_slab, obj); } }