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