/* * \brief Region manager session interface * \author Norman Feske * \date 2006-05-15 */ /* * 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 _INCLUDE__RM_SESSION__RM_SESSION_H_ #define _INCLUDE__RM_SESSION__RM_SESSION_H_ #include #include #include #include #include #include #include namespace Genode { struct Rm_session; } struct Genode::Rm_session : Session { enum Fault_type { READY = 0, READ_FAULT = 1, WRITE_FAULT = 2, EXEC_FAULT = 3 }; /** * State of region-manager session * * If a client accesses a location outside the regions attached to * the region-manager session, a fault occurs and gets signalled to * the registered fault handler. The fault handler, in turn needs * the information about the fault address and fault type to * resolve the fault. This information is represented by this * structure. */ struct State { /** * Type of occurred fault */ Fault_type type; /** * Fault address */ addr_t addr; /** * Default constructor */ State() : type(READY), addr(0) { } /** * Constructor */ State(Fault_type fault_type, addr_t fault_addr) : type(fault_type), addr(fault_addr) { } }; /** * Helper for tranferring the bit representation of a pointer as RPC * argument. */ class Local_addr { private: void *_ptr; public: template Local_addr(T ptr) : _ptr((void *)ptr) { } Local_addr() : _ptr(0) { } template operator T () { return (T)_ptr; } }; static const char *service_name() { return "RM"; } /********************* ** Exception types ** *********************/ class Attach_failed : public Exception { }; class Invalid_args : public Attach_failed { }; class Invalid_dataspace : public Attach_failed { }; class Region_conflict : public Attach_failed { }; class Out_of_metadata : public Attach_failed { }; class Invalid_thread : public Exception { }; class Unbound_thread : public Exception { }; /** * Destructor */ virtual ~Rm_session() { } /** * Map dataspace into local address space * * \param ds capability of dataspace to map * \param size size of the locally mapped region * default (0) is the whole dataspace * \param offset start at offset in dataspace (page-aligned) * \param use_local_addr if set to true, attach the dataspace at * the specified 'local_addr' * \param local_addr local destination address * \param executable if the mapping should be executable * * \throw Attach_failed if dataspace or offset is invalid, * or on region conflict * \throw Out_of_metadata if meta-data backing store is exhausted * * \return local address of mapped dataspace * */ virtual Local_addr attach(Dataspace_capability ds, size_t size = 0, off_t offset = 0, bool use_local_addr = false, Local_addr local_addr = (void *)0, bool executable = false) = 0; /** * Shortcut for attaching a dataspace at a predefined local address */ Local_addr attach_at(Dataspace_capability ds, addr_t local_addr, size_t size = 0, off_t offset = 0) { return attach(ds, size, offset, true, local_addr); } /** * Shortcut for attaching a dataspace executable at a predefined local address */ Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr, size_t size = 0, off_t offset = 0) { return attach(ds, size, offset, true, local_addr, true); } /** * Remove region from local address space */ virtual void detach(Local_addr local_addr) = 0; /** * Add client to pager * * \param thread thread that will be paged * \throw Invalid_thread * \throw Out_of_metadata * \throw Unbound_thread * \return capability to be used for handling page faults * * This method must be called at least once to establish a valid * communication channel between the pager part of the region manager * and the client thread. */ virtual Pager_capability add_client(Thread_capability thread) = 0; /** * Remove client from pager * * \param pager pager capability of client to be removed */ virtual void remove_client(Pager_capability) = 0; /** * Register signal handler for region-manager faults * * On Linux, this signal is never delivered because page-fault handling * is performed by the Linux kernel. On microkernel platforms, * unresolvable page faults (traditionally called segmentation fault) * will result in the delivery of the signal. */ virtual void fault_handler(Signal_context_capability handler) = 0; /** * Request current state of RM session */ virtual State state() = 0; /** * Return dataspace representation of region-manager session */ virtual Dataspace_capability dataspace() = 0; /********************* ** RPC declaration ** *********************/ GENODE_RPC_THROW(Rpc_attach, Local_addr, attach, GENODE_TYPE_LIST(Invalid_dataspace, Region_conflict, Out_of_metadata, Invalid_args), Dataspace_capability, size_t, off_t, bool, Local_addr, bool); GENODE_RPC(Rpc_detach, void, detach, Local_addr); GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client, GENODE_TYPE_LIST(Unbound_thread, Invalid_thread, Out_of_metadata), Thread_capability); GENODE_RPC(Rpc_remove_client, void, remove_client, Pager_capability); GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability); GENODE_RPC(Rpc_state, State, state); GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace); GENODE_RPC_INTERFACE(Rpc_attach, Rpc_detach, Rpc_add_client, Rpc_remove_client, Rpc_fault_handler, Rpc_state, Rpc_dataspace); }; #endif /* _INCLUDE__RM_SESSION__RM_SESSION_H_ */