1  /*
   2   * \brief  Region manager session interface
   3   * \author Norman Feske
   4   * \date   2006-05-15
   5   */

   6  
   7  /*
   8   * Copyright (C) 2006-2013 Genode Labs GmbH
   9   *
  10   * This file is part of the Genode OS framework, which is distributed
  11   * under the terms of the GNU General Public License version 2.
  12   */

  13  
  14  #ifndef _INCLUDE__RM_SESSION__RM_SESSION_H_
  15  #define _INCLUDE__RM_SESSION__RM_SESSION_H_
  16  
  17  #include <base/exception.h>
  18  #include <base/stdint.h>
  19  #include <base/signal.h>
  20  #include <dataspace/capability.h>
  21  #include <thread/capability.h>
  22  #include <pager/capability.h>
  23  #include <session/session.h>
  24  
  25  namespace Genode {
  26  
  27     struct Rm_session : Session
  28     {
  29        enum Fault_type {
  30           READY = 0, READ_FAULT = 1, WRITE_FAULT = 2, EXEC_FAULT = 3 }
;

  31  
  32        /**
  33         * State of region-manager session
  34         *
  35         * If a client accesses a location outside the regions attached to
  36         * the region-manager session, a fault occurs and gets signalled to
  37         * the registered fault handler. The fault handler, in turn needs
  38         * the information about the fault address and fault type to
  39         * resolve the fault. This information is represented by this
  40         * structure.
  41         */

  42        struct State
  43        {
  44           /**
  45            * Type of occurred fault
  46            */

  47           Fault_type type;
  48  
  49           /**
  50            * Fault address
  51            */

  52           addr_t addr;
  53  
  54           /**
  55            * Default constructor
  56            */

  57           State() : type(READY), addr(0) { }

  58  
  59           /**
  60            * Constructor
  61            */

  62           State(Fault_type fault_type, addr_t fault_addr) :
  63              type(fault_type), addr(fault_addr)
 { }

  64        }
;

  65  
  66  
  67        /**
  68         * Helper for tranferring the bit representation of a pointer as RPC
  69         * argument.
  70         */

  71        class Local_addr
  72        {
  73           private:
  74  
  75              void *_ptr;

  76  
  77           public:
  78  
  79              template <typename T>
  80              Local_addr(ptr) : _ptr((void *)ptr) { }
  81  
  82              Local_addr() : _ptr(0) { }
  83  
  84              template <typename T>
  85              operator T () { return (T)_ptr; }

  86        }
;

  87  
  88  
  89        static const char *service_name() { return "RM"; }
  90  
  91  
  92        /*********************
  93         ** Exception types **
  94         *********************/

  95  
  96        class Attach_failed     : public Exception     { };
  97        class Invalid_args      : public Attach_failed { };
  98        class Invalid_dataspace : public Attach_failed { };
  99        class Region_conflict   : public Attach_failed { };
 100        class Out_of_metadata   : public Attach_failed { };
 101  
 102        class Invalid_thread    : public Exception { };
 103        class Unbound_thread    : public Exception { };
 104  
 105        /**
 106         * Destructor
 107         */

 108        virtual ~Rm_session() { }

 109  
 110        /**
 111         * Map dataspace into local address space
 112         *
 113         * \param ds               capability of dataspace to map
 114         * \param size             size of the locally mapped region
 115         *                         default (0) is the whole dataspace
 116         * \param offset           start at offset in dataspace (page-aligned)
 117         * \param use_local_addr   if set to true, attach the dataspace at
 118         *                         the specified `local_addr`
 119         * \param local_addr       local destination address
 120         * \param executable       if the mapping should be executable
 121         *
 122         * \throw Attach_failed    if dataspace or offset is invalid,
 123         *                         or on region conflict
 124         * \throw Out_of_metadata  if meta-data backing store is exhausted
 125         *
 126         * \return                 local address of mapped dataspace
 127         *
 128         */

 129        virtual Local_addr attach(Dataspace_capability ds,
 130                                  size_t size = 0, off_t offset = 0,
 131                                  bool use_local_addr = false,
 132                                  Local_addr local_addr = (void *)0,
 133                                  bool executable = false)
 = 0;

 134  
 135        /**
 136         * Shortcut for attaching a dataspace at a predefined local address
 137         */

 138        Local_addr attach_at(Dataspace_capability ds, addr_t local_addr,
 139                             size_t size = 0, off_t offset = 0)
 {
 140           return attach(ds, size, offset, true, local_addr); }

 141  
 142        /**
 143         * Shortcut for attaching a dataspace executable at a predefined local address
 144         */

 145        Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr,
 146                                     size_t size = 0, off_t offset = 0)
 {
 147           return attach(ds, size, offset, true, local_addr, true); }

 148  
 149        /**
 150         * Remove region from local address space
 151         */

 152        virtual void detach(Local_addr local_addr) = 0;

 153  
 154        /**
 155         * Add client to pager
 156         *
 157         * \param thread  thread that will be paged
 158         * \throw         Invalid_thread
 159         * \throw         Out_of_metadata
 160         * \throw         Unbound_thread
 161         * \return        capability to be used for handling page faults
 162         *
 163         * This method must be called at least once to establish a valid
 164         * communication channel between the pager part of the region manager
 165         * and the client thread.
 166         */

 167        virtual Pager_capability add_client(Thread_capability thread) = 0;

 168  
 169        /**
 170         * Remove client from pager
 171         *
 172         * \param pager  pager capability of client to be removed
 173         */

 174        virtual void remove_client(Pager_capability) = 0;

 175  
 176        /**
 177         * Register signal handler for region-manager faults
 178         *
 179         * On Linux, this signal is never delivered because page-fault handling
 180         * is performed by the Linux kernel. On microkernel platforms,
 181         * unresolvable page faults (traditionally called segmentation fault)
 182         * will result in the delivery of the signal.
 183         */

 184        virtual void fault_handler(Signal_context_capability handler) = 0;

 185  
 186        /**
 187         * Request current state of RM session
 188         */

 189        virtual State state() = 0;

 190  
 191        /**
 192         * Return dataspace representation of region-manager session
 193         */

 194        virtual Dataspace_capability dataspace() = 0;

 195  
 196  
 197        /*********************
 198         ** RPC declaration **
 199         *********************/

 200  
 201        GENODE_RPC_THROW(Rpc_attach, Local_addr, attach,
 202                         GENODE_TYPE_LIST(Invalid_dataspace, Region_conflict,
 203                                          Out_of_metadata, Invalid_args)
,
 204                         Dataspace_capability, size_t, off_t, bool, Local_addr, bool)
;
 205        GENODE_RPC(Rpc_detach, void, detach, Local_addr);
 206        GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client,
 207                         GENODE_TYPE_LIST(Invalid_thread, Out_of_metadata),
 208                         Thread_capability)
;
 209        GENODE_RPC(Rpc_remove_client, void, remove_client, Pager_capability);
 210        GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability);
 211        GENODE_RPC(Rpc_state, State, state);
 212        GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace);
 213  
 214        GENODE_RPC_INTERFACE(Rpc_attach, Rpc_detach, Rpc_add_client,
 215                             Rpc_remove_client, Rpc_fault_handler, Rpc_state,
 216                             Rpc_dataspace)
;
 217     }
;

 218  }

 219  
 220  #endif /* _INCLUDE__RM_SESSION__RM_SESSION_H_ */