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 { struct Rm_session; }
26
27
28 struct Genode::Rm_session : Session
29 {
30 enum Fault_type {
31 READY = 0, READ_FAULT = 1, WRITE_FAULT = 2, EXEC_FAULT = 3 };
32
33 /**
34 * State of region-manager session
35 *
36 * If a client accesses a location outside the regions attached to
37 * the region-manager session, a fault occurs and gets signalled to
38 * the registered fault handler. The fault handler, in turn needs
39 * the information about the fault address and fault type to
40 * resolve the fault. This information is represented by this
41 * structure.
42 */
43 struct State
44 {
45 /**
46 * Type of occurred fault
47 */
48 Fault_type type;
49
50 /**
51 * Fault address
52 */
53 addr_t addr;
54
55 /**
56 * Default constructor
57 */
58 State() : type(READY), addr(0) { }
59
60 /**
61 * Constructor
62 */
63 State(Fault_type fault_type, addr_t fault_addr) :
64 type(fault_type), addr(fault_addr) { }
65 };
66
67
68 /**
69 * Helper for tranferring the bit representation of a pointer as RPC
70 * argument.
71 */
72 class Local_addr
73 {
74 private:
75
76 void *_ptr;
77
78 public:
79
80 template <typename T>
81 Local_addr(T ptr) : _ptr((void *)ptr) { }
82
83 Local_addr() : _ptr(0) { }
84
85 template <typename T>
86 operator T () { return (T)_ptr; }
87 };
88
89
90 static const char *service_name() { return "RM"; }
91
92
93 /*********************
94 ** Exception types **
95 *********************/
96
97 class Attach_failed : public Exception { };
98 class Invalid_args : public Attach_failed { };
99 class Invalid_dataspace : public Attach_failed { };
100 class Region_conflict : public Attach_failed { };
101 class Out_of_metadata : public Attach_failed { };
102
103 class Invalid_thread : public Exception { };
104 class Unbound_thread : public Exception { };
105
106 /**
107 * Destructor
108 */
109 virtual ~Rm_session() { }
110
111 /**
112 * Map dataspace into local address space
113 *
114 * \param ds capability of dataspace to map
115 * \param size size of the locally mapped region
116 * default (0) is the whole dataspace
117 * \param offset start at offset in dataspace (page-aligned)
118 * \param use_local_addr if set to true, attach the dataspace at
119 * the specified `local_addr`
120 * \param local_addr local destination address
121 * \param executable if the mapping should be executable
122 *
123 * \throw Attach_failed if dataspace or offset is invalid,
124 * or on region conflict
125 * \throw Out_of_metadata if meta-data backing store is exhausted
126 *
127 * \return local address of mapped dataspace
128 *
129 */
130 virtual Local_addr attach(Dataspace_capability ds,
131 size_t size = 0, off_t offset = 0,
132 bool use_local_addr = false,
133 Local_addr local_addr = (void *)0,
134 bool executable = false) = 0;
135
136 /**
137 * Shortcut for attaching a dataspace at a predefined local address
138 */
139 Local_addr attach_at(Dataspace_capability ds, addr_t local_addr,
140 size_t size = 0, off_t offset = 0) {
141 return attach(ds, size, offset, true, local_addr); }
142
143 /**
144 * Shortcut for attaching a dataspace executable at a predefined local address
145 */
146 Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr,
147 size_t size = 0, off_t offset = 0) {
148 return attach(ds, size, offset, true, local_addr, true); }
149
150 /**
151 * Remove region from local address space
152 */
153 virtual void detach(Local_addr local_addr) = 0;
154
155 /**
156 * Add client to pager
157 *
158 * \param thread thread that will be paged
159 * \throw Invalid_thread
160 * \throw Out_of_metadata
161 * \throw Unbound_thread
162 * \return capability to be used for handling page faults
163 *
164 * This method must be called at least once to establish a valid
165 * communication channel between the pager part of the region manager
166 * and the client thread.
167 */
168 virtual Pager_capability add_client(Thread_capability thread) = 0;
169
170 /**
171 * Remove client from pager
172 *
173 * \param pager pager capability of client to be removed
174 */
175 virtual void remove_client(Pager_capability) = 0;
176
177 /**
178 * Register signal handler for region-manager faults
179 *
180 * On Linux, this signal is never delivered because page-fault handling
181 * is performed by the Linux kernel. On microkernel platforms,
182 * unresolvable page faults (traditionally called segmentation fault)
183 * will result in the delivery of the signal.
184 */
185 virtual void fault_handler(Signal_context_capability handler) = 0;
186
187 /**
188 * Request current state of RM session
189 */
190 virtual State state() = 0;
191
192 /**
193 * Return dataspace representation of region-manager session
194 */
195 virtual Dataspace_capability dataspace() = 0;
196
197
198 /*********************
199 ** RPC declaration **
200 *********************/
201
202 GENODE_RPC_THROW(Rpc_attach, Local_addr, attach,
203 GENODE_TYPE_LIST(Invalid_dataspace, Region_conflict,
204 Out_of_metadata, Invalid_args),
205 Dataspace_capability, size_t, off_t, bool, Local_addr, bool);
206 GENODE_RPC(Rpc_detach, void, detach, Local_addr);
207 GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client,
208 GENODE_TYPE_LIST(Unbound_thread, Invalid_thread, Out_of_metadata),
209 Thread_capability);
210 GENODE_RPC(Rpc_remove_client, void, remove_client, Pager_capability);
211 GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability);
212 GENODE_RPC(Rpc_state, State, state);
213 GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace);
214
215 GENODE_RPC_INTERFACE(Rpc_attach, Rpc_detach, Rpc_add_client,
216 Rpc_remove_client, Rpc_fault_handler, Rpc_state,
217 Rpc_dataspace);
218 };
219
220 #endif /* _INCLUDE__RM_SESSION__RM_SESSION_H_ */