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