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(T 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_ */