/* * \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-' 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 #include #include /* local includes */ #include namespace Genode { struct Expanding_rm_session_client; struct Expanding_cpu_session_client; class Platform_env; } struct Genode::Expanding_rm_session_client : Upgradeable_client { Expanding_rm_session_client(Rm_session_capability cap) : Upgradeable_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( [&] () { 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( [&] () { return Rm_session_client::add_client(thread); }, [&] () { upgrade_ram(8*1024); }); } }; struct Genode::Expanding_cpu_session_client : Upgradeable_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 (static_cap_cast(cap)) { } Thread_capability create_thread(Name const &name, addr_t utcb) { return retry( [&] () { 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 Capability request(Parent &parent, char const *service) { return static_cap_cast(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(parent, "Env::ram_session")), cpu_cap(request(parent, "Env::cpu_session")), rm (request (parent, "Env::rm_session")), pd (request (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_ */