1 /**
2 * \file
3 * Sigma0 interface
4 *
5 * \ingroup l4sigma0_api
6 */
7 /*
8 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9 * Alexander Warg <warg@os.inf.tu-dresden.de>,
10 * Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
11 * economic rights: Technische Universität Dresden (Germany)
12 * This file is part of TUD:OS and distributed under the terms of the
13 * GNU Lesser General Public License 2.1.
14 * Please see the COPYING-LGPL-2.1 file for details.
15 */
16 #ifndef __L4_SIGMA0_SIGMA0_H
17 #define __L4_SIGMA0_SIGMA0_H
18
19 /**
20 * \defgroup l4sigma0_api Sigma0 API
21 *
22 * Sigma0 API bindings.
23 *
24 * Convenience bindings for the Sigma0 protocol.
25 */
26
27 #include <l4/sys/compiler.h>
28 #include <l4/sys/types.h>
29 #include <l4/sys/kip.h>
30
31 /**
32 * \defgroup l4sigma0_api_internal Internal constants
33 * \ingroup l4sigma0_api
34 * Internal sigma0 definitions.
35 */
36 /*@{*/
37 #undef SIGMA0_REQ_MAGIC
38 #undef SIGMA0_REQ_MASK
39
40 # define SIGMA0_REQ_MAGIC ~0xFFUL /**< Request magic */
41 # define SIGMA0_REQ_MASK ~0xFFUL /**< Request mask */
42
43 /* Starting with 0x60 allows to detect components which still use the old
44 * constants (0x00 ... 0x50) */
45 #define SIGMA0_REQ_ID_MASK 0xF0 /**< ID mask */
46 #define SIGMA0_REQ_ID_FPAGE_RAM 0x60 /**< RAM */
47 #define SIGMA0_REQ_ID_FPAGE_IOMEM 0x70 /**< I/O memory */
48 #define SIGMA0_REQ_ID_FPAGE_IOMEM_CACHED 0x80 /**< Cached I/O memory */
49 #define SIGMA0_REQ_ID_FPAGE_ANY 0x90 /**< Any */
50 #define SIGMA0_REQ_ID_KIP 0xA0 /**< KIP */
51 #define SIGMA0_REQ_ID_DEBUG_DUMP 0xC0 /**< Debug dump */
52 #define SIGMA0_REQ_ID_NEW_CLIENT 0xD0 /**< New client */
53
54 #define SIGMA0_IS_MAGIC_REQ(d1) \
55 ((d1 & SIGMA0_REQ_MASK) == SIGMA0_REQ_MAGIC) /**< Check if magic */
56
57 #define SIGMA0_REQ(x) \
58 (SIGMA0_REQ_MAGIC + SIGMA0_REQ_ID_ ## x) /**< Construct */
59
60 /* Use these constants in your code! */
61 #define SIGMA0_REQ_FPAGE_RAM (SIGMA0_REQ(FPAGE_RAM)) /**< RAM */
62 #define SIGMA0_REQ_FPAGE_IOMEM (SIGMA0_REQ(FPAGE_IOMEM)) /**< I/O memory */
63 #define SIGMA0_REQ_FPAGE_IOMEM_CACHED (SIGMA0_REQ(FPAGE_IOMEM_CACHED)) /**< Cache I/O memory*/
64 #define SIGMA0_REQ_FPAGE_ANY (SIGMA0_REQ(FPAGE_ANY)) /**< Any */
65 #define SIGMA0_REQ_KIP (SIGMA0_REQ(KIP)) /**< KIP */
66 #define SIGMA0_REQ_DEBUG_DUMP (SIGMA0_REQ(DEBUG_DUMP)) /**< Debug dump */
67 #define SIGMA0_REQ_NEW_CLIENT (SIGMA0_REQ(NEW_CLIENT)) /**< New client */
68 /*@}*/
69
70 /**
71 * \addtogroup l4sigma0_api
72 */
73 /*@{*/
74
75 /**
76 * Return flags of libsigma0 functions.
77 */
78 enum l4sigma0_return_flags_t {
79 L4SIGMA0_OK, /**< Ok */
80 L4SIGMA0_NOTALIGNED, /**< Phys, virt or size not aligned */
81 L4SIGMA0_IPCERROR, /**< IPC error */
82 L4SIGMA0_NOFPAGE, /**< No fpage received */
83 L4SIGMA0_4,
84 L4SIGMA0_5,
85 L4SIGMA0_SMALLERFPAGE, /**< Superpage requested but smaller flexpage received */
86 };
87
88 EXTERN_C_BEGIN
89
90 /**
91 * Map the kernel info page from sigma0 to addr.
92 *
93 * \param sigma0 Capability selector for the sigma0 gate.
94 * \param addr Start of the receive window to receive KIP in.
95 * \param log2_size Size of the receive window to receive KIP in.
96 *
97 * \return Address KIP was mapped to, 0 indicates an error.
98 */
99 L4_CV l4_kernel_info_t *
100 l4sigma0_map_kip(l4_cap_idx_t sigma0, void *addr, unsigned log2_size);
101
102 /**
103 * Request a memory mapping from sigma0.
104 *
105 * \param sigma0 Capability selector for the sigma0 gate.
106 * \param phys The physical address of the requested page (must be at least
107 * aligned to the minimum page size).
108 * \param virt The virtual address where the paged should be mapped in the
109 * local address space (must be at least aligned to the minimum
110 * page size).
111 * \param size The size of the requested page, this must be a multiple of
112 * the minimum page size.
113 *
114 * \retval 0 Success.
115 * \retval -L4SIGMA0_NOTALIGNED `phys`, `virt`, or `size` are not aligned.
116 * \retval -L4SIGMA0_IPCERROR IPC error.
117 * \retval -L4SIGMA0_NOFPAGE No fpage received.
118 *
119 * This function only maps normal RAM. To map other memory, use
120 * l4sigma0_map_iomem(). See also there for the distinction between both memory
121 * types.
122 *
123 * This is the direct method to request memory from sigma0. There is also the
124 * indirect method where sigma0 will answer page faults with a mapping that is
125 * one-to-one between the faulting virtual page and the backing physical page.
126 * See L4::Pager::page_fault(). For an overview of the memory hierarchy, see
127 * \ref l4re_concepts_ds_rm.
128 *
129 * See l4sigma0_map_errstr() to get a description of the return value.
130 */
131 L4_CV int l4sigma0_map_mem(l4_cap_idx_t sigma0,
132 l4_addr_t phys, l4_addr_t virt, l4_addr_t size);
133
134 /**
135 * Request IO memory from sigma0.
136 *
137 * \param sigma0 Capability selector for the sigma0 gate.
138 * \param phys The physical address to be requested (page aligned).
139 * \param virt The virtual address where the memory should be mapped to
140 * (page aligned).
141 * \param size The size of the IO memory area to be mapped (multiple of
142 * page size)
143 * \param cached Requests cacheable IO memory if 1 and uncached if 0.
144 *
145 * \retval 0 Success.
146 * \retval -L4SIGMA0_NOTALIGNED `phys`, `virt`, or `size` are not aligned.
147 * \retval -L4SIGMA0_IPCERROR IPC error.
148 * \retval -L4SIGMA0_NOFPAGE No fpage received.
149 *
150 * This function is similar to l4sigma0_map_mem(), the difference is that it
151 * requests IO memory. IO memory is everything that is not known to be normal
152 * RAM. Also ACPI tables or the BIOS memory is treated as IO memory.
153 *
154 * See l4sigma0_map_errstr() to get a description of the return value.
155 */
156 L4_CV int l4sigma0_map_iomem(l4_cap_idx_t sigma0, l4_addr_t phys,
157 l4_addr_t virt, l4_addr_t size, int cached);
158 /**
159 * Request an arbitrary free page of RAM.
160 *
161 * \param sigma0 Capability selector for the sigma0 gate.
162 * \param map_area The base address of the local virtual memory area
163 * where the page should be mapped.
164 * \param log2_map_size The size of the requested page log 2 (the size in
165 * bytes is 2^log2_map_size). This must be at least the
166 * minimal page size. By specifing larger sizes the
167 * largest possible hardware page size will be used.
168 * \param[out] base Physical address of the page received (i.e. the send
169 * base of the received mapping if any).
170 * \param sz Size to map by the server in 2^sz bytes.
171 *
172 * \retval 0 Success.
173 * \retval -L4SIGMA0_IPCERROR IPC error.
174 * \retval -L4SIGMA0_NOFPAGE No fpage received.
175 *
176 * This function requests arbitrary free memory from sigma0. It should be used
177 * whenever spare memory is needed, instead of requesting specific physical
178 * memory with l4sigma0_map_mem().
179 *
180 * See l4sigma0_map_errstr() to get a description of the return value.
181 */
182 L4_CV int l4sigma0_map_anypage(l4_cap_idx_t sigma0, l4_addr_t map_area,
183 unsigned log2_map_size, l4_addr_t *base,
184 unsigned sz);
185
186 /**
187 * Request sigma0 to dump internal debug information.
188 *
189 * \param sigma0 Capability selector for the sigma0 gate.
190 *
191 * The debug information, such as internal memory maps, as well as statistics
192 * about the internal allocators is dumped to the kernel debugger.
193 */
194 L4_CV void l4sigma0_debug_dump(l4_cap_idx_t sigma0);
195
196 /**
197 * Create a new IPC gate for a new Sigma0 client.
198 *
199 * \param sigma0 Capability selector for the sigma0 gate.
200 * \param gate Capability selector to use for the new gate.
201 *
202 * \retval 0 Success.
203 * \retval -L4SIGMA0_IPCERROR IPC error.
204 * \retval -L4SIGMA0_NOFPAGE No fpage received.
205 */
206 L4_CV int l4sigma0_new_client(l4_cap_idx_t sigma0, l4_cap_idx_t gate);
207
208 /**
209 * Get user readable error messages for the return codes.
210 *
211 * \param err The error code reported by the *map* functions.
212 *
213 * \return A string containing the error message.
214 */
215 L4_INLINE char const *l4sigma0_map_errstr(int err);
216
217 /*@}*/
218
219
220 /* Implementations */
221
l4sigma0_map_errstr(int err)222 L4_INLINE char const *l4sigma0_map_errstr(int err)
223 {
224 switch (err)
225 {
226 case 0: return "No error";
227 case -1: return "Phys, virt or size not aligned";
228 case -2: return "IPC error";
229 case -3: return "No fpage received";
230 #ifndef SIGMA0_REQ_MAGIC
231 case -4: return "Bad physical address (old protocol only)";
232 #endif
233 case -6: return "Superpage requested but smaller flexpage received";
234 case -7: return "Cannot map I/O memory cacheable (old protocol only)";
235 default: return "Unknown error";
236 }
237 }
238
239
240 EXTERN_C_END
241
242 #endif /* ! __L4_SIGMA0_SIGMA0_H */
243