genode/base/src/base/env/platform_env.h

167 lines
4.8 KiB
C++

/*
* \brief Platform environment of Genode process
* \author Norman Feske
* \author Christian Helmuth
* \date 2006-07-28
*
* This file is a generic variant of the platform environment, which is
* suitable for platforms such as L4ka::Pistachio and L4/Fiasco. On other
* platforms, it may be replaced by a platform-specific version residing
* in the corresponding 'base-<platform>' repository.
*/
/*
* Copyright (C) 2006-2013 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 _PLATFORM_ENV_H_
#define _PLATFORM_ENV_H_
/* Genode includes */
#include <base/printf.h>
#include <base/env.h>
#include <base/heap.h>
/* local includes */
#include <platform_env_common.h>
namespace Genode {
struct Expanding_rm_session_client;
struct Expanding_cpu_session_client;
class Platform_env;
}
struct Genode::Expanding_rm_session_client : Upgradeable_client<Genode::Rm_session_client>
{
Expanding_rm_session_client(Rm_session_capability cap)
: Upgradeable_client<Genode::Rm_session_client>(cap) { }
Local_addr attach(Dataspace_capability ds, size_t size, off_t offset,
bool use_local_addr, Local_addr local_addr,
bool executable)
{
return retry<Rm_session::Out_of_metadata>(
[&] () {
return Rm_session_client::attach(ds, size, offset,
use_local_addr,
local_addr,
executable); },
[&] () { upgrade_ram(8*1024); });
}
Pager_capability add_client(Thread_capability thread)
{
return retry<Rm_session::Out_of_metadata>(
[&] () { return Rm_session_client::add_client(thread); },
[&] () { upgrade_ram(8*1024); });
}
};
struct Genode::Expanding_cpu_session_client : Upgradeable_client<Genode::Cpu_session_client>
{
Expanding_cpu_session_client(Genode::Cpu_session_capability cap)
:
/*
* We need to upcast the capability because on some platforms (i.e.,
* NOVA), 'Cpu_session_client' refers to a platform-specific session
* interface ('Nova_cpu_session').
*/
Upgradeable_client<Genode::Cpu_session_client>
(static_cap_cast<Genode::Cpu_session_client::Rpc_interface>(cap))
{ }
Thread_capability create_thread(Name const &name, addr_t utcb)
{
return retry<Cpu_session::Out_of_metadata>(
[&] () { return Cpu_session_client::create_thread(name, utcb); },
[&] () { upgrade_ram(8*1024); });
}
};
class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve
{
private:
Expanding_parent_client _parent_client;
struct Resources
{
template <typename T>
Capability<T> request(Parent &parent, char const *service) {
return static_cap_cast<T>(parent.session(service, "")); }
Ram_session_capability ram_cap;
Expanding_ram_session_client ram = { ram_cap };
Cpu_session_capability cpu_cap;
Expanding_cpu_session_client cpu = { cpu_cap };
Expanding_rm_session_client rm;
Pd_session_client pd;
Resources(Parent &parent) :
ram_cap(request<Ram_session>(parent, "Env::ram_session")),
cpu_cap(request<Cpu_session>(parent, "Env::cpu_session")),
rm (request<Rm_session> (parent, "Env::rm_session")),
pd (request<Pd_session> (parent, "Env::pd_session"))
{ }
};
Resources _resources;
Heap _heap;
char _initial_heap_chunk[sizeof(addr_t) * 4096];
/*
* Emergency RAM reserve
*
* See the comment of '_fallback_sig_cap()' in 'env/env.cc'.
*/
constexpr static size_t _emergency_ram_size() { return 4*1024; }
Ram_dataspace_capability _emergency_ram_ds;
public:
/**
* Standard constructor
*/
Platform_env()
:
_parent_client(Genode::parent_cap(), *this),
_resources(_parent_client),
_heap(&_resources.ram, &_resources.rm, Heap::UNLIMITED,
_initial_heap_chunk, sizeof(_initial_heap_chunk)),
_emergency_ram_ds(_resources.ram.alloc(_emergency_ram_size()))
{ }
void reload_parent_cap(Native_capability::Dst, long);
/*************************************
** Emergency_ram_reserve interface **
*************************************/
void release() { _resources.ram.free(_emergency_ram_ds); }
/*******************
** Env interface **
*******************/
Parent *parent() { return &_parent_client; }
Ram_session *ram_session() { return &_resources.ram; }
Ram_session_capability ram_session_cap() { return _resources.ram_cap; }
Cpu_session *cpu_session() { return &_resources.cpu; }
Cpu_session_capability cpu_session_cap() { return _resources.cpu_cap; }
Rm_session *rm_session() { return &_resources.rm; }
Pd_session *pd_session() { return &_resources.pd; }
Allocator *heap() { return &_heap; }
};
#endif /* _PLATFORM_ENV_H_ */