mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 06:33:31 +00:00
base: remove local capability from generic base
* Instead of using local capabilities within core's context area implementation for stack allocation/attachment, simply do both operations while stack gets attached, thereby getting rid of the local capabilities in generic code * In base-hw the UTCB of core's main thread gets mapped directly instead of constructing a dataspace component out of it and hand over its local capability * Remove local capability implementation from all platforms except Linux Ref #1443
This commit is contained in:
parent
a168c9d6ce
commit
b949489641
@ -78,9 +78,7 @@ namespace Genode {
|
|||||||
* Native_capability in Fiasco.OC is just a reference to a Cap_index.
|
* Native_capability in Fiasco.OC is just a reference to a Cap_index.
|
||||||
*
|
*
|
||||||
* As Cap_index objects cannot be copied around, but Native_capability
|
* As Cap_index objects cannot be copied around, but Native_capability
|
||||||
* have to, we have to use this indirection. Moreover, it might instead
|
* have to, we have to use this indirection.
|
||||||
* of a Cap_index reference some process-local object, and thereby
|
|
||||||
* implements a local capability.
|
|
||||||
*/
|
*/
|
||||||
class Native_capability
|
class Native_capability
|
||||||
{
|
{
|
||||||
@ -97,18 +95,9 @@ namespace Genode {
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
Cap_index* _idx;
|
Cap_index* _idx;
|
||||||
void* _ptr;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a local capability, used by derived Capability
|
|
||||||
* class only
|
|
||||||
*
|
|
||||||
* \param ptr pointer to process-local object
|
|
||||||
*/
|
|
||||||
Native_capability(void* ptr) : _idx(0), _ptr(ptr) { }
|
|
||||||
|
|
||||||
inline void _inc()
|
inline void _inc()
|
||||||
{
|
{
|
||||||
if (_idx)
|
if (_idx)
|
||||||
@ -127,21 +116,18 @@ namespace Genode {
|
|||||||
/**
|
/**
|
||||||
* Default constructor creates an invalid capability
|
* Default constructor creates an invalid capability
|
||||||
*/
|
*/
|
||||||
Native_capability() : _idx(0), _ptr(0) { }
|
Native_capability() : _idx(0) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct capability manually
|
* Construct capability manually
|
||||||
*/
|
*/
|
||||||
Native_capability(Cap_index* idx)
|
Native_capability(Cap_index* idx)
|
||||||
: _idx(idx), _ptr(0) { _inc(); }
|
: _idx(idx) { _inc(); }
|
||||||
|
|
||||||
Native_capability(const Native_capability &o)
|
Native_capability(const Native_capability &o)
|
||||||
: _idx(o._idx), _ptr(o._ptr) { _inc(); }
|
: _idx(o._idx) { _inc(); }
|
||||||
|
|
||||||
~Native_capability()
|
~Native_capability() { _dec(); }
|
||||||
{
|
|
||||||
_dec();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return Cap_index object referenced by this object
|
* Return Cap_index object referenced by this object
|
||||||
@ -152,14 +138,13 @@ namespace Genode {
|
|||||||
* Overloaded comparision operator
|
* Overloaded comparision operator
|
||||||
*/
|
*/
|
||||||
bool operator==(const Native_capability &o) const {
|
bool operator==(const Native_capability &o) const {
|
||||||
return (_ptr) ? _ptr == o._ptr : _idx == o._idx; }
|
return _idx == o._idx; }
|
||||||
|
|
||||||
Native_capability& operator=(const Native_capability &o){
|
Native_capability& operator=(const Native_capability &o){
|
||||||
if (this == &o)
|
if (this == &o)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
_dec();
|
_dec();
|
||||||
_ptr = o._ptr;
|
|
||||||
_idx = o._idx;
|
_idx = o._idx;
|
||||||
_inc();
|
_inc();
|
||||||
return *this;
|
return *this;
|
||||||
@ -172,7 +157,6 @@ namespace Genode {
|
|||||||
long local_name() const { return _idx ? _idx->id() : 0; }
|
long local_name() const { return _idx ? _idx->id() : 0; }
|
||||||
Dst dst() const { return _idx ? Dst(_idx->kcap()) : Dst(); }
|
Dst dst() const { return _idx ? Dst(_idx->kcap()) : Dst(); }
|
||||||
bool valid() const { return (_idx != 0) && _idx->valid(); }
|
bool valid() const { return (_idx != 0) && _idx->valid(); }
|
||||||
void *local() const { return _ptr; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,13 +49,6 @@ using namespace Fiasco;
|
|||||||
|
|
||||||
void Ipc_ostream::_marshal_capability(Native_capability const &cap)
|
void Ipc_ostream::_marshal_capability(Native_capability const &cap)
|
||||||
{
|
{
|
||||||
/* first transfer local capability value */
|
|
||||||
_write_to_buf(cap.local());
|
|
||||||
|
|
||||||
/* if it's a local capability we're done */
|
|
||||||
if (cap.local())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (cap.valid()) {
|
if (cap.valid()) {
|
||||||
if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst()))) {
|
if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst()))) {
|
||||||
_write_to_buf(0);
|
_write_to_buf(0);
|
||||||
@ -80,15 +73,6 @@ void Ipc_istream::_unmarshal_capability(Native_capability &cap)
|
|||||||
{
|
{
|
||||||
long value = 0;
|
long value = 0;
|
||||||
|
|
||||||
/* get local capability pointer from message buffer */
|
|
||||||
_read_from_buf(value);
|
|
||||||
|
|
||||||
/* if it's a local capability, the pointer is marshalled in the id */
|
|
||||||
if (value) {
|
|
||||||
cap = Capability<Native_capability>::local_cap((Native_capability*)value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* extract capability id from message buffer */
|
/* extract capability id from message buffer */
|
||||||
_read_from_buf(value);
|
_read_from_buf(value);
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ namespace Fiasco {
|
|||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
** Cap_index_allocator **
|
** Cap_index_allocator **
|
||||||
***************************/
|
***************************/
|
||||||
|
@ -22,6 +22,7 @@ namespace Kernel {
|
|||||||
Pd * core_pd();
|
Pd * core_pd();
|
||||||
Mode_transition_control * mtc();
|
Mode_transition_control * mtc();
|
||||||
Pic * pic();
|
Pic * pic();
|
||||||
|
Native_utcb * core_main_thread_utcb_phys_addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _KERNEL__KERNEL_H_ */
|
#endif /* _KERNEL__KERNEL_H_ */
|
||||||
|
@ -46,6 +46,7 @@ extern void * _start_secondary_cpus;
|
|||||||
extern int _prog_img_beg;
|
extern int _prog_img_beg;
|
||||||
extern int _prog_img_end;
|
extern int _prog_img_end;
|
||||||
|
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
/* import Genode types */
|
/* import Genode types */
|
||||||
@ -190,6 +191,10 @@ namespace Kernel
|
|||||||
Pic * Kernel::pic() { return unmanaged_singleton<Pic>(); }
|
Pic * Kernel::pic() { return unmanaged_singleton<Pic>(); }
|
||||||
|
|
||||||
|
|
||||||
|
Native_utcb* Kernel::core_main_thread_utcb_phys_addr() {
|
||||||
|
return unmanaged_singleton<Native_utcb,Genode::get_page_size()>(); }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable kernel-entry assembly to get an exclusive stack for every CPU
|
* Enable kernel-entry assembly to get an exclusive stack for every CPU
|
||||||
*/
|
*/
|
||||||
@ -244,18 +249,14 @@ void init_kernel_mp_primary()
|
|||||||
*(Core_thread_id *)s = 0;
|
*(Core_thread_id *)s = 0;
|
||||||
|
|
||||||
/* initialize UTCB and map it */
|
/* initialize UTCB and map it */
|
||||||
static Native_utcb utcb __attribute__((aligned(get_page_size())));
|
Native_utcb * utcb = Kernel::core_main_thread_utcb_phys_addr();
|
||||||
static Dataspace_component main_utcb_ds(sizeof(Native_utcb),
|
Genode::map_local((addr_t)utcb, (addr_t)UTCB_MAIN_THREAD,
|
||||||
(addr_t)UTCB_MAIN_THREAD,
|
|
||||||
(addr_t)&utcb, CACHED, true, 0);
|
|
||||||
Genode::map_local((addr_t)&utcb, (addr_t)UTCB_MAIN_THREAD,
|
|
||||||
sizeof(Native_utcb) / get_page_size());
|
sizeof(Native_utcb) / get_page_size());
|
||||||
|
|
||||||
static Kernel::Thread t(Cpu_priority::max, 0, "core");
|
static Kernel::Thread t(Cpu_priority::max, 0, "core");
|
||||||
|
|
||||||
/* start thread with stack pointer at the top of stack */
|
/* start thread with stack pointer at the top of stack */
|
||||||
utcb.start_info()->init(t.id(),
|
utcb->start_info()->init(t.id(), Dataspace_capability());
|
||||||
Dataspace_capability::local_cap(&main_utcb_ds));
|
|
||||||
t.ip = (addr_t)&_core_start;
|
t.ip = (addr_t)&_core_start;
|
||||||
t.sp = (addr_t)s + STACK_SIZE;
|
t.sp = (addr_t)s + STACK_SIZE;
|
||||||
t.init(cpu_pool()->primary_cpu(), core_pd(),
|
t.init(cpu_pool()->primary_cpu(), core_pd(),
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include <base/env.h>
|
#include <base/env.h>
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
|
#include <map_local.h>
|
||||||
|
#include <kernel/kernel.h>
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <platform_thread.h>
|
#include <platform_thread.h>
|
||||||
|
|
||||||
@ -57,17 +59,11 @@ void Thread_base::_init_platform_thread(size_t, Type type)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t const utcb_size = sizeof(Native_utcb);
|
|
||||||
addr_t const context_area = Native_config::context_area_virtual_base();
|
|
||||||
addr_t const utcb_new = (addr_t)&_context->utcb - context_area;
|
|
||||||
Rm_session * const rm = env_context_area_rm_session();
|
|
||||||
|
|
||||||
/* remap initial main-thread UTCB according to context-area spec */
|
/* remap initial main-thread UTCB according to context-area spec */
|
||||||
try { rm->attach_at(_main_thread_utcb_ds, utcb_new, utcb_size); }
|
Genode::map_local((addr_t)Kernel::core_main_thread_utcb_phys_addr(),
|
||||||
catch(...) {
|
(addr_t)&_context->utcb,
|
||||||
PERR("failed to re-map UTCB");
|
max(sizeof(Native_utcb) / get_page_size(), (size_t)1));
|
||||||
while (1) ;
|
|
||||||
}
|
|
||||||
/* adjust initial object state in case of a main thread */
|
/* adjust initial object state in case of a main thread */
|
||||||
tid().thread_id = _main_thread_id;
|
tid().thread_id = _main_thread_id;
|
||||||
}
|
}
|
||||||
|
60
repos/base-linux/include/base/local_capability.h
Normal file
60
repos/base-linux/include/base/local_capability.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* \brief Local capability
|
||||||
|
* \author Norman Feske
|
||||||
|
* \author Stefan Kalkowski
|
||||||
|
* \date 2011-05-22
|
||||||
|
*
|
||||||
|
* A typed capability is a capability tied to one specifiec RPC interface
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE__BASE_LINUX__CAPABILITY_H_
|
||||||
|
#define _INCLUDE__BASE_LINUX__CAPABILITY_H_
|
||||||
|
|
||||||
|
#include <base/capability.h>
|
||||||
|
|
||||||
|
namespace Genode {
|
||||||
|
template <typename> class Local_capability;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local capability referring to a specific RPC interface
|
||||||
|
*
|
||||||
|
* \param RPC_INTERFACE class containing the RPC interface declaration
|
||||||
|
*/
|
||||||
|
template <typename RPC_INTERFACE>
|
||||||
|
class Genode::Local_capability
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method to construct a local-capability.
|
||||||
|
*
|
||||||
|
* Local-capabilities can be used protection-domain internally
|
||||||
|
* only. They simply incorporate a pointer to some process-local
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* \param ptr pointer to the corresponding local object.
|
||||||
|
* \return a capability that represents the local object.
|
||||||
|
*/
|
||||||
|
static Capability<RPC_INTERFACE> local_cap(RPC_INTERFACE* ptr) {
|
||||||
|
Untyped_capability cap(Cap_dst_policy::Dst(), (long)ptr);
|
||||||
|
return reinterpret_cap_cast<RPC_INTERFACE>(cap); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dereference a local-capability.
|
||||||
|
*
|
||||||
|
* \param c the local-capability.
|
||||||
|
* \return pointer to the corresponding local object.
|
||||||
|
*/
|
||||||
|
static RPC_INTERFACE* deref(Capability<RPC_INTERFACE> c) {
|
||||||
|
return reinterpret_cast<RPC_INTERFACE*>(c.local_name()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE_LINUX__CAPABILITY_H_ */
|
@ -15,6 +15,7 @@
|
|||||||
#define _INCLUDE__RM_SESSION__CLIENT_H_
|
#define _INCLUDE__RM_SESSION__CLIENT_H_
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
|
#include <base/local_capability.h>
|
||||||
#include <rm_session/capability.h>
|
#include <rm_session/capability.h>
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode {
|
||||||
@ -28,7 +29,8 @@ namespace Genode {
|
|||||||
*
|
*
|
||||||
* \throw Local_interface::Non_local_capability
|
* \throw Local_interface::Non_local_capability
|
||||||
*/
|
*/
|
||||||
Rm_session *_local() const { return Rm_session_capability::deref(*this); }
|
Rm_session *_local() const {
|
||||||
|
return Local_capability<Rm_session>::deref(*this); }
|
||||||
|
|
||||||
explicit Rm_session_client(Rm_session_capability session)
|
explicit Rm_session_client(Rm_session_capability session)
|
||||||
: Rm_session_capability(session) { }
|
: Rm_session_capability(session) { }
|
||||||
|
@ -33,7 +33,7 @@ Platform_env_base::Rm_session_mmap::_dataspace_size(Dataspace_capability ds)
|
|||||||
if (ds.valid())
|
if (ds.valid())
|
||||||
return Dataspace_client(ds).size();
|
return Dataspace_client(ds).size();
|
||||||
|
|
||||||
return Dataspace_capability::deref(ds)->size();
|
return Local_capability<Dataspace>::deref(ds)->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ Platform_env::Local_parent::session(Service_name const &service_name,
|
|||||||
Rm_session_mmap *rm = new (env()->heap())
|
Rm_session_mmap *rm = new (env()->heap())
|
||||||
Rm_session_mmap(true, size);
|
Rm_session_mmap(true, size);
|
||||||
|
|
||||||
return Session_capability::local_cap(rm);
|
return Local_capability<Session>::local_cap(rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Expanding_parent_client::session(service_name, args, affinity);
|
return Expanding_parent_client::session(service_name, args, affinity);
|
||||||
@ -100,7 +100,7 @@ void Platform_env::Local_parent::close(Session_capability session)
|
|||||||
*/
|
*/
|
||||||
Capability<Rm_session_mmap> rm = static_cap_cast<Rm_session_mmap>(session);
|
Capability<Rm_session_mmap> rm = static_cap_cast<Rm_session_mmap>(session);
|
||||||
|
|
||||||
destroy(env()->heap(), Capability<Rm_session_mmap>::deref(rm));
|
destroy(env()->heap(), Local_capability<Rm_session_mmap>::deref(rm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
7
repos/base-linux/src/base/env/platform_env.h
vendored
7
repos/base-linux/src/base/env/platform_env.h
vendored
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <util/misc_math.h>
|
#include <util/misc_math.h>
|
||||||
|
#include <base/local_capability.h>
|
||||||
#include <base/heap.h>
|
#include <base/heap.h>
|
||||||
#include <linux_cpu_session/client.h>
|
#include <linux_cpu_session/client.h>
|
||||||
|
|
||||||
@ -307,10 +308,8 @@ namespace Genode {
|
|||||||
* as argument to 'Rm_session_mmap::attach'. It is not a
|
* as argument to 'Rm_session_mmap::attach'. It is not a
|
||||||
* real capability.
|
* real capability.
|
||||||
*/
|
*/
|
||||||
Dataspace_capability dataspace()
|
Dataspace_capability dataspace() {
|
||||||
{
|
return Local_capability<Dataspace>::local_cap(this); }
|
||||||
return Dataspace_capability::local_cap(this);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
|
#include <base/local_capability.h>
|
||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
#include <linux_dataspace/client.h>
|
#include <linux_dataspace/client.h>
|
||||||
#include <linux_syscalls.h>
|
#include <linux_syscalls.h>
|
||||||
@ -49,7 +50,7 @@ static bool is_sub_rm_session(Dataspace_capability ds)
|
|||||||
if (ds.valid())
|
if (ds.valid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return Dataspace_capability::deref(ds) != 0;
|
return Local_capability<Dataspace>::deref(ds) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -231,7 +232,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
|
|||||||
|
|
||||||
if (is_sub_rm_session(ds)) {
|
if (is_sub_rm_session(ds)) {
|
||||||
|
|
||||||
Dataspace *ds_if = Dataspace_capability::deref(ds);
|
Dataspace *ds_if = Local_capability<Dataspace>::deref(ds);
|
||||||
|
|
||||||
Rm_session_mmap *rm = dynamic_cast<Rm_session_mmap *>(ds_if);
|
Rm_session_mmap *rm = dynamic_cast<Rm_session_mmap *>(ds_if);
|
||||||
|
|
||||||
@ -355,7 +356,7 @@ void Platform_env::Rm_session_mmap::detach(Rm_session::Local_addr local_addr)
|
|||||||
*/
|
*/
|
||||||
if (is_sub_rm_session(region.dataspace())) {
|
if (is_sub_rm_session(region.dataspace())) {
|
||||||
|
|
||||||
Dataspace *ds_if = Dataspace_capability::deref(region.dataspace());
|
Dataspace *ds_if = Local_capability<Dataspace>::deref(region.dataspace());
|
||||||
Rm_session_mmap *rm = dynamic_cast<Rm_session_mmap *>(ds_if);
|
Rm_session_mmap *rm = dynamic_cast<Rm_session_mmap *>(ds_if);
|
||||||
if (rm)
|
if (rm)
|
||||||
rm->_base = 0;
|
rm->_base = 0;
|
||||||
|
@ -181,7 +181,7 @@ Genode::size_t
|
|||||||
Platform_env_base::Rm_session_mmap::_dataspace_size(Capability<Dataspace> ds_cap)
|
Platform_env_base::Rm_session_mmap::_dataspace_size(Capability<Dataspace> ds_cap)
|
||||||
{
|
{
|
||||||
if (!ds_cap.valid())
|
if (!ds_cap.valid())
|
||||||
return Dataspace_capability::deref(ds_cap)->size();
|
return Local_capability<Dataspace>::deref(ds_cap)->size();
|
||||||
|
|
||||||
/* use RPC if called from a different thread */
|
/* use RPC if called from a different thread */
|
||||||
if (!core_env()->entrypoint()->is_myself()) {
|
if (!core_env()->entrypoint()->is_myself()) {
|
||||||
|
@ -41,7 +41,7 @@ namespace Genode {
|
|||||||
inline bool operator == (Native_thread_id t1, Native_thread_id t2)
|
inline bool operator == (Native_thread_id t1, Native_thread_id t2)
|
||||||
{
|
{
|
||||||
return (t1.ec_sel == t2.ec_sel) &&
|
return (t1.ec_sel == t2.ec_sel) &&
|
||||||
(t1.exc_pt_sel == t2.exc_pt_sel);
|
(t1.exc_pt_sel == t2.exc_pt_sel);
|
||||||
}
|
}
|
||||||
inline bool operator != (Native_thread_id t1, Native_thread_id t2)
|
inline bool operator != (Native_thread_id t1, Native_thread_id t2)
|
||||||
{
|
{
|
||||||
@ -99,18 +99,12 @@ namespace Genode {
|
|||||||
} _cap;
|
} _cap;
|
||||||
|
|
||||||
bool _trans_map;
|
bool _trans_map;
|
||||||
void * _ptr;
|
|
||||||
addr_t _rcv_window;
|
addr_t _rcv_window;
|
||||||
|
|
||||||
enum { INVALID_INDEX = ~0UL };
|
enum { INVALID_INDEX = ~0UL };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
explicit
|
|
||||||
Native_capability(void* ptr)
|
|
||||||
: _cap(), _trans_map(true), _ptr(ptr),
|
|
||||||
_rcv_window(INVALID_INDEX) {}
|
|
||||||
|
|
||||||
inline void _inc(bool inc_if_one = false) const
|
inline void _inc(bool inc_if_one = false) const
|
||||||
{
|
{
|
||||||
Cap_index idx(cap_map()->find(local_name()));
|
Cap_index idx(cap_map()->find(local_name()));
|
||||||
@ -130,7 +124,7 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Native_capability()
|
Native_capability()
|
||||||
: _cap(), _trans_map(true), _ptr(0), _rcv_window(INVALID_INDEX) {}
|
: _cap(), _trans_map(true), _rcv_window(INVALID_INDEX) {}
|
||||||
|
|
||||||
explicit
|
explicit
|
||||||
Native_capability(addr_t sel, unsigned rights = 0x1f)
|
Native_capability(addr_t sel, unsigned rights = 0x1f)
|
||||||
@ -143,12 +137,11 @@ namespace Genode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_trans_map = true;
|
_trans_map = true;
|
||||||
_ptr = 0;
|
|
||||||
_rcv_window = INVALID_INDEX;
|
_rcv_window = INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
Native_capability(const Native_capability &o)
|
Native_capability(const Native_capability &o)
|
||||||
: _cap(o._cap), _trans_map(o._trans_map), _ptr(o._ptr),
|
: _cap(o._cap), _trans_map(o._trans_map),
|
||||||
_rcv_window(o._rcv_window) { if (valid()) _inc(); }
|
_rcv_window(o._rcv_window) { if (valid()) _inc(); }
|
||||||
|
|
||||||
~Native_capability() { if (valid()) _dec(); }
|
~Native_capability() { if (valid()) _dec(); }
|
||||||
@ -157,7 +150,7 @@ namespace Genode {
|
|||||||
* Overloaded comparison operator
|
* Overloaded comparison operator
|
||||||
*/
|
*/
|
||||||
bool operator==(const Native_capability &o) const {
|
bool operator==(const Native_capability &o) const {
|
||||||
return (_ptr) ? _ptr == o._ptr : local_name() == o.local_name(); }
|
return local_name() == o.local_name(); }
|
||||||
|
|
||||||
Native_capability operator+ () const
|
Native_capability operator+ () const
|
||||||
{
|
{
|
||||||
@ -178,7 +171,6 @@ namespace Genode {
|
|||||||
|
|
||||||
_cap = o._cap;
|
_cap = o._cap;
|
||||||
_trans_map = o._trans_map;
|
_trans_map = o._trans_map;
|
||||||
_ptr = o._ptr;
|
|
||||||
_rcv_window = o._rcv_window;
|
_rcv_window = o._rcv_window;
|
||||||
|
|
||||||
if (valid()) _inc();
|
if (valid()) _inc();
|
||||||
@ -187,19 +179,13 @@ namespace Genode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the selector of the Native_cap and
|
* Check whether the selector of the Native_cap and
|
||||||
* the capability type is valid.
|
* the capability type is valid.
|
||||||
*/
|
*/
|
||||||
bool valid() const { return !_cap.dst.is_null(); }
|
bool valid() const { return !_cap.dst.is_null(); }
|
||||||
|
|
||||||
Dst dst() const { return _cap.dst; }
|
Dst dst() const { return _cap.dst; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Return pointer to the server object identified by
|
|
||||||
* this cap
|
|
||||||
*/
|
|
||||||
void * local() const { return _ptr; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the local_name. On NOVA it is the same as the
|
* Return the local_name. On NOVA it is the same as the
|
||||||
* destination value.
|
* destination value.
|
||||||
@ -247,7 +233,7 @@ namespace Genode {
|
|||||||
* Return true if the cap should be tried first to
|
* Return true if the cap should be tried first to
|
||||||
* be translated and if this fails it should be mapped.
|
* be translated and if this fails it should be mapped.
|
||||||
*/
|
*/
|
||||||
bool trans_map() const { return _trans_map; }
|
bool trans_map() const { return _trans_map; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int Native_connection_state;
|
typedef int Native_connection_state;
|
||||||
|
@ -135,14 +135,6 @@ class Genode::Capability : public Untyped_capability
|
|||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor, should be used by the local-capability
|
|
||||||
* factory method only.
|
|
||||||
*
|
|
||||||
* \param ptr pointer to the local object this capability represents.
|
|
||||||
*/
|
|
||||||
Capability(void *ptr) : Untyped_capability(ptr) {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for the return type instantiated by 'call' overloads
|
* Wrapper for the return type instantiated by 'call' overloads
|
||||||
*
|
*
|
||||||
@ -186,28 +178,6 @@ class Genode::Capability : public Untyped_capability
|
|||||||
*/
|
*/
|
||||||
Capability() { }
|
Capability() { }
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory method to construct a local-capability.
|
|
||||||
*
|
|
||||||
* Local-capabilities can be used protection-domain internally
|
|
||||||
* only. They simply incorporate a pointer to some process-local
|
|
||||||
* object.
|
|
||||||
*
|
|
||||||
* \param ptr pointer to the corresponding local object.
|
|
||||||
* \return a capability that represents the local object.
|
|
||||||
*/
|
|
||||||
static Capability<RPC_INTERFACE> local_cap(RPC_INTERFACE* ptr) {
|
|
||||||
return Capability<RPC_INTERFACE>((void*)ptr); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dereference a local-capability.
|
|
||||||
*
|
|
||||||
* \param c the local-capability.
|
|
||||||
* \return pointer to the corresponding local object.
|
|
||||||
*/
|
|
||||||
static RPC_INTERFACE* deref(Capability<RPC_INTERFACE> c) {
|
|
||||||
return reinterpret_cast<RPC_INTERFACE*>(c.local()); }
|
|
||||||
|
|
||||||
template <typename IF>
|
template <typename IF>
|
||||||
typename Trait::Call_return<typename IF::Ret_type>::Type
|
typename Trait::Call_return<typename IF::Ret_type>::Type
|
||||||
call() const
|
call() const
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* \brief Support code for the thread API
|
* \brief Support code for the thread API
|
||||||
* \author Norman Feske
|
* \author Norman Feske
|
||||||
|
* \author Stefan Kalkowski
|
||||||
* \date 2010-01-13
|
* \date 2010-01-13
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
* Copyright (C) 2010-2015 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -25,37 +26,54 @@
|
|||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pointer to dataspace used to hold core contexts
|
|
||||||
*/
|
|
||||||
enum { MAX_CORE_CONTEXTS = 256 };
|
|
||||||
static Dataspace_component *context_ds[MAX_CORE_CONTEXTS];
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Region-manager session for allocating thread contexts
|
* Region-manager session for allocating thread contexts
|
||||||
*
|
*
|
||||||
* This class corresponds to the managed dataspace that is normally
|
* This class corresponds to the managed dataspace that is normally
|
||||||
* used for organizing thread contexts with the thread context area.
|
* used for organizing thread contexts with the thread context area.
|
||||||
* It "emulates" the sub address space by adjusting the local address
|
* In contrast to the ordinary implementation, core's version does
|
||||||
* argument to 'attach' with the offset of the thread context area.
|
* not split between allocation of memory and virtual memory management.
|
||||||
|
* Due to the missing availability of "real" dataspaces and capabilities
|
||||||
|
* refering to it without having an entrypoint in place, the allocation
|
||||||
|
* of a dataspace has no effect, but the attachment of the thereby "empty"
|
||||||
|
* dataspace is doing both: allocation and attachment.
|
||||||
*/
|
*/
|
||||||
class Context_area_rm_session : public Rm_session
|
class Context_area_rm_session : public Rm_session
|
||||||
{
|
{
|
||||||
enum { verbose = false };
|
private:
|
||||||
|
|
||||||
|
using Ds_slab = Synchronized_allocator<Tslab<Dataspace_component,
|
||||||
|
get_page_size()> >;
|
||||||
|
|
||||||
|
Ds_slab _ds_slab { platform()->core_mem_alloc() };
|
||||||
|
|
||||||
|
enum { verbose = false };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach backing store to thread-context area
|
* Allocate and attach on-the-fly backing store to thread-context area
|
||||||
*/
|
*/
|
||||||
Local_addr attach(Dataspace_capability ds_cap,
|
Local_addr attach(Dataspace_capability ds_cap, /* ignored capability */
|
||||||
size_t size, off_t offset,
|
size_t size, off_t offset,
|
||||||
bool use_local_addr, Local_addr local_addr,
|
bool use_local_addr, Local_addr local_addr,
|
||||||
bool executable)
|
bool executable)
|
||||||
{
|
{
|
||||||
Dataspace_component *ds =
|
/* allocate physical memory */
|
||||||
dynamic_cast<Dataspace_component*>(Dataspace_capability::deref(ds_cap));
|
size = round_page(size);
|
||||||
|
void *phys_base;
|
||||||
|
Range_allocator *ra = platform_specific()->ram_alloc();
|
||||||
|
if (ra->alloc_aligned(size, &phys_base,
|
||||||
|
get_page_size_log2()).is_error()) {
|
||||||
|
PERR("could not allocate backing store for new context");
|
||||||
|
return (addr_t)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
PDBG("phys_base = %p, size = 0x%zx", phys_base, size);
|
||||||
|
|
||||||
|
Dataspace_component *ds = new (&_ds_slab)
|
||||||
|
Dataspace_component(size, 0, (addr_t)phys_base, CACHED, true, 0);
|
||||||
if (!ds) {
|
if (!ds) {
|
||||||
PERR("dataspace for core context does not exist");
|
PERR("dataspace for core context does not exist");
|
||||||
return (addr_t)0;
|
return (addr_t)0;
|
||||||
@ -70,7 +88,8 @@ class Context_area_rm_session : public Rm_session
|
|||||||
|
|
||||||
if (!map_local(ds->phys_addr(), core_local_addr,
|
if (!map_local(ds->phys_addr(), core_local_addr,
|
||||||
ds->size() >> get_page_size_log2())) {
|
ds->size() >> get_page_size_log2())) {
|
||||||
PERR("could not map phys %lx at local %lx", ds->phys_addr(), core_local_addr);
|
PERR("could not map phys %lx at local %lx",
|
||||||
|
ds->phys_addr(), core_local_addr);
|
||||||
return (addr_t)0;
|
return (addr_t)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,35 +98,7 @@ class Context_area_rm_session : public Rm_session
|
|||||||
return local_addr;
|
return local_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void detach(Local_addr local_addr)
|
void detach(Local_addr local_addr) { PWRN("Not implemented!"); }
|
||||||
{
|
|
||||||
addr_t core_local_addr = Native_config::context_area_virtual_base() +
|
|
||||||
(addr_t)local_addr;
|
|
||||||
|
|
||||||
Dataspace_component *ds = 0;
|
|
||||||
|
|
||||||
/* find the dataspace component for the given address */
|
|
||||||
for (unsigned i = 0; i < MAX_CORE_CONTEXTS; i++) {
|
|
||||||
if (context_ds[i] &&
|
|
||||||
(core_local_addr >= context_ds[i]->core_local_addr()) &&
|
|
||||||
(core_local_addr < (context_ds[i]->core_local_addr() +
|
|
||||||
context_ds[i]->size()))) {
|
|
||||||
ds = context_ds[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ds) {
|
|
||||||
PERR("dataspace for core context does not exist");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
PDBG("core_local_addr = %lx, phys_addr = %lx, size = 0x%zx",
|
|
||||||
ds->core_local_addr(), ds->phys_addr(), ds->size());
|
|
||||||
|
|
||||||
Genode::unmap_local(ds->core_local_addr(), ds->size() >> get_page_size_log2());
|
|
||||||
}
|
|
||||||
|
|
||||||
Pager_capability add_client(Thread_capability) {
|
Pager_capability add_client(Thread_capability) {
|
||||||
return Pager_capability(); }
|
return Pager_capability(); }
|
||||||
@ -124,76 +115,18 @@ class Context_area_rm_session : public Rm_session
|
|||||||
|
|
||||||
class Context_area_ram_session : public Ram_session
|
class Context_area_ram_session : public Ram_session
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
|
|
||||||
enum { verbose = false };
|
|
||||||
|
|
||||||
using Ds_slab = Synchronized_allocator<Tslab<Dataspace_component,
|
|
||||||
get_page_size()> >;
|
|
||||||
|
|
||||||
Ds_slab _ds_slab { platform()->core_mem_alloc() };
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached)
|
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) {
|
||||||
{
|
return reinterpret_cap_cast<Ram_dataspace>(Native_capability()); }
|
||||||
/* find free context */
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < MAX_CORE_CONTEXTS; i++)
|
|
||||||
if (!context_ds[i])
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i == MAX_CORE_CONTEXTS) {
|
void free(Ram_dataspace_capability ds) {
|
||||||
PERR("maximum number of core contexts (%d) reached", MAX_CORE_CONTEXTS);
|
PWRN("Not implemented!"); }
|
||||||
return Ram_dataspace_capability();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate physical memory */
|
|
||||||
size = round_page(size);
|
|
||||||
void *phys_base;
|
|
||||||
if (platform_specific()->ram_alloc()->alloc_aligned(size, &phys_base,
|
|
||||||
get_page_size_log2()).is_error()) {
|
|
||||||
PERR("could not allocate backing store for new context");
|
|
||||||
return Ram_dataspace_capability();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
PDBG("phys_base = %p, size = 0x%zx", phys_base, size);
|
|
||||||
|
|
||||||
context_ds[i] = new (&_ds_slab)
|
|
||||||
Dataspace_component(size, 0, (addr_t)phys_base, CACHED, true, 0);
|
|
||||||
|
|
||||||
Dataspace_capability cap = Dataspace_capability::local_cap(context_ds[i]);
|
|
||||||
return static_cap_cast<Ram_dataspace>(cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void free(Ram_dataspace_capability ds)
|
|
||||||
{
|
|
||||||
Dataspace_component *dataspace_component =
|
|
||||||
dynamic_cast<Dataspace_component*>(Dataspace_capability::deref(ds));
|
|
||||||
|
|
||||||
if (!dataspace_component)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < MAX_CORE_CONTEXTS; i++)
|
|
||||||
if (context_ds[i] == dataspace_component) {
|
|
||||||
context_ds[i] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *phys_addr = (void*)dataspace_component->phys_addr();
|
|
||||||
size_t size = dataspace_component->size();
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
PDBG("phys_addr = %p, size = 0x%zx", phys_addr, size);
|
|
||||||
|
|
||||||
destroy(&_ds_slab, dataspace_component);
|
|
||||||
platform_specific()->ram_alloc()->free(phys_addr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ref_account(Ram_session_capability ram_session) { return 0; }
|
int ref_account(Ram_session_capability ram_session) { return 0; }
|
||||||
|
|
||||||
int transfer_quota(Ram_session_capability ram_session, size_t amount) { return 0; }
|
int transfer_quota(Ram_session_capability ram_session, size_t amount) {
|
||||||
|
return 0; }
|
||||||
|
|
||||||
size_t quota() { return 0; }
|
size_t quota() { return 0; }
|
||||||
|
|
||||||
@ -218,4 +151,3 @@ namespace Genode {
|
|||||||
return &inst;
|
return &inst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user