1 /**
2 * \file
3 * Environment interface
4 */
5 /*
6 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7 * Alexander Warg <warg@os.inf.tu-dresden.de>
8 * economic rights: Technische Universität Dresden (Germany)
9 *
10 * This file is part of TUD:OS and distributed under the terms of the
11 * GNU General Public License 2.
12 * Please see the COPYING-GPL-2 file for details.
13 *
14 * As a special exception, you may use this file as part of a free software
15 * library without restriction. Specifically, if other files instantiate
16 * templates or use macros or inline functions from this file, or you compile
17 * this file and link it with other files to produce an executable, this
18 * file does not by itself cause the resulting executable to be covered by
19 * the GNU General Public License. This exception does not however
20 * invalidate any other reasons why the executable file might be covered by
21 * the GNU General Public License.
22 */
23 #pragma once
24
25 #include <l4/sys/consts.h>
26 #include <l4/sys/types.h>
27 #include <l4/sys/kip.h>
28 #include <l4/sys/compiler.h>
29
30 #include <l4/re/consts.h>
31
32 /**
33 * \defgroup api_l4re_env Initial Environment
34 * \ingroup api_l4re_c
35 *
36 * C interface of the initial environment that is provided to an L4 task.
37 *
38 * \includefile{l4/re/env.h}
39 *
40 * For an explanation of the default task capabilites see \ref
41 * l4_default_caps_t.
42 *
43 * For the C++ interface refer to L4Re::Env.
44 */
45
46 /**
47 * Entry in the L4Re environment array for the named inital objects.
48 * \ingroup api_l4re_env
49 */
50 typedef struct l4re_env_cap_entry_t
51 {
52 /**
53 * The capability selector for the object.
54 */
55 l4_cap_idx_t cap;
56
57 /**
58 * Some flags for the object.
59 * \note Currently unused.
60 */
61 l4_umword_t flags;
62
63 /**
64 * The name of the object.
65 */
66 char name[16];
67 #ifdef __cplusplus
68
69 /**
70 * Create an invalid entry.
71 */
l4re_env_cap_entry_tl4re_env_cap_entry_t72 l4re_env_cap_entry_t() L4_NOTHROW : cap(L4_INVALID_CAP), flags(~0) {}
73
74 /**
75 * Create an entry with the name \a n, capability \a c, and flags \a f.
76 *
77 * \param n is the name of the initial object.
78 * \param c is the capability selector that refers the initial object.
79 * \param f are the additional flags for the object.
80 */
81 l4re_env_cap_entry_t(char const *n, l4_cap_idx_t c, l4_umword_t f = 0) L4_NOTHROW
capl4re_env_cap_entry_t82 : cap(c), flags(f)
83 {
84 for (unsigned i = 0; n && i < sizeof(name); ++i, ++n)
85 {
86 name[i] = *n;
87 if (!*n)
88 break;
89 }
90 }
91
is_valid_namel4re_env_cap_entry_t92 static bool is_valid_name(char const *n) L4_NOTHROW
93 {
94 for (unsigned i = 0; *n; ++i, ++n)
95 if (i > sizeof(name))
96 return false;
97
98 return true;
99 }
100 #endif
101 } l4re_env_cap_entry_t;
102
103
104 /**
105 * Initial environment data structure
106 *
107 * \see \link api_l4re_env Initial environment \endlink
108 */
109 typedef struct l4re_env_t
110 {
111 l4_cap_idx_t parent; /**< Parent object-capability */
112 l4_cap_idx_t rm; /**< Region map object-capability */
113 l4_cap_idx_t mem_alloc; /**< Memory allocator object-capability */
114 l4_cap_idx_t log; /**< Logging object-capability */
115 l4_cap_idx_t main_thread; /**< Object-capability of the first user thread */
116 l4_cap_idx_t factory; /**< Object-capability of the factory available to the task */
117 l4_cap_idx_t scheduler; /**< Object capability for the scheduler set to use */
118 l4_cap_idx_t first_free_cap; /**< First capability index available to the application */
119 l4_fpage_t utcb_area; /**< UTCB area of the task */
120 l4_addr_t first_free_utcb; /**< First UTCB within the UTCB area available to the application */
121 l4re_env_cap_entry_t *caps;
122 } l4re_env_t;
123
124 /**
125 * \internal
126 * Pointer to L4Re initial environment.
127 * \ingroup api_l4re_env
128 */
129 extern l4re_env_t *l4re_global_env;
130
131
132 /**
133 * Get L4Re initial environment.
134 * \ingroup api_l4re_env
135 * \return Pointer to L4Re initial environment.
136 */
137 L4_INLINE l4re_env_t *l4re_env(void) L4_NOTHROW;
138
139 /*
140 * FIXME: this seems to be at the wrong place here
141 */
142 /**
143 * Get Kernel Info Page.
144 * \ingroup api_l4re_env
145 * \return Pointer to Kernel Info Page (KIP) structure.
146 */
147 L4_INLINE l4_kernel_info_t *l4re_kip(void) L4_NOTHROW;
148
149
150 /**
151 * Get the capability selector for the object named \a name.
152 * \ingroup api_l4re_env
153 * \param name is the name of the object to lookup in the initial objects.
154 * \return A valid capability selector if the object exists or an invalid
155 * capability selector if not (l4_is_invalid_cap()).
156 */
157 L4_INLINE l4_cap_idx_t
158 l4re_env_get_cap(char const *name) L4_NOTHROW;
159
160 /**
161 * Get the capability selector for the object named \a name.
162 * \ingroup api_l4re_env
163 * \param name is the name of the object to lookup in the initial objects.
164 * \param e is the environment structure to use for the operation.
165 * \return A valid capability selector if the object exists or an invalid
166 * capability selector if not (l4_is_invalid_cap()).
167 */
168 L4_INLINE l4_cap_idx_t
169 l4re_env_get_cap_e(char const *name, l4re_env_t const *e) L4_NOTHROW;
170
171 /**
172 * Get the full l4re_env_cap_entry_t for the object named \a name.
173 * \ingroup api_l4re_env
174 * \param name is the name of the object to lookup in the initial objects.
175 * \param l is the length of the name string, thus \a name might not be zero
176 * terminated.
177 * \param e is the environment structure to use for the operation.
178 * \return A pointer to an l4re_env_cap_entry_t if the object exists or
179 * NULL if not.
180 */
181 L4_INLINE l4re_env_cap_entry_t const *
182 l4re_env_get_cap_l(char const *name, unsigned l, l4re_env_t const *e) L4_NOTHROW;
183
184 L4_INLINE
l4re_env()185 l4re_env_t *l4re_env() L4_NOTHROW
186 { return l4re_global_env; }
187
188 L4_INLINE
l4re_kip()189 l4_kernel_info_t *l4re_kip() L4_NOTHROW
190 {
191 extern char __L4_KIP_ADDR__[];
192 return (l4_kernel_info_t *)__L4_KIP_ADDR__;
193 }
194
195 L4_INLINE l4re_env_cap_entry_t const *
l4re_env_get_cap_l(char const * name,unsigned l,l4re_env_t const * e)196 l4re_env_get_cap_l(char const *name, unsigned l, l4re_env_t const *e) L4_NOTHROW
197 {
198 l4re_env_cap_entry_t const *c = e->caps;
199 for (; c && c->flags != ~0UL; ++c)
200 {
201 unsigned i;
202 for (i = 0;
203 i < sizeof(c->name) && i < l && c->name[i] && name[i] && name[i] == c->name[i];
204 ++i)
205 ;
206
207 if (i == l && (i == sizeof(c->name) || !c->name[i]))
208 return c;
209 }
210 return NULL;
211 }
212
213 L4_INLINE l4_cap_idx_t
l4re_env_get_cap_e(char const * name,l4re_env_t const * e)214 l4re_env_get_cap_e(char const *name, l4re_env_t const *e) L4_NOTHROW
215 {
216 unsigned l;
217 l4re_env_cap_entry_t const *r;
218 for (l = 0; name[l]; ++l) ;
219 r = l4re_env_get_cap_l(name, l, e);
220 if (r)
221 return r->cap;
222
223 return L4_INVALID_CAP;
224 }
225
226 L4_INLINE l4_cap_idx_t
l4re_env_get_cap(char const * name)227 l4re_env_get_cap(char const *name) L4_NOTHROW
228 { return l4re_env_get_cap_e(name, l4re_env()); }
229
230