1// -*- Mode: C++ -*-
2// vim:ft=cpp
3/**
4 * \file
5 * Environment interface
6 */
7/*
8 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9 *               Alexander Warg <warg@os.inf.tu-dresden.de>,
10 *               Björn Döbel <doebel@os.inf.tu-dresden.de>
11 *     economic rights: Technische Universität Dresden (Germany)
12 *
13 * This file is part of TUD:OS and distributed under the terms of the
14 * GNU General Public License 2.
15 * Please see the COPYING-GPL-2 file for details.
16 *
17 * As a special exception, you may use this file as part of a free software
18 * library without restriction.  Specifically, if other files instantiate
19 * templates or use macros or inline functions from this file, or you compile
20 * this file and link it with other files to produce an executable, this
21 * file does not by itself cause the resulting executable to be covered by
22 * the GNU General Public License.  This exception does not however
23 * invalidate any other reasons why the executable file might be covered by
24 * the GNU General Public License.
25 */
26#pragma once
27
28#include <l4/sys/types.h>
29
30#include <l4/re/rm>
31#include <l4/re/parent>
32#include <l4/re/mem_alloc>
33#include <l4/re/log>
34#include <l4/re/consts>
35
36#include <l4/re/env.h>
37
38namespace L4 {
39class Scheduler;
40}
41
42/**
43 * L4 Runtime Environment.
44 */
45namespace L4Re
46{
47  /**
48   * C++ interface of the initial environment that is provided to an L4 task.
49   *
50   * The initial environment is provided to each L4 task that is started
51   * by an L4Re conform loader, such as the Moe root task. The initial
52   * environment provides access to a set of initial capabilities and
53   * some additional information about the available resources, such as
54   * free UTCBs (see \link l4_utcb_api Virtual Registers \endlink) and
55   * available entries in capability table (provided by the micro kernel).
56   *
57   * Each of the initial capabilities is stored at a fixed index in the
58   * task's capability table and the L4 runtime environment provides
59   * convenience functions to retrieve the capabilities. See the table below
60   * for an comprehensive overview.
61   *
62   * Name         | Object Type     | Convenience Function
63   * ------------ | --------------- | --------------------
64   * parent       | L4Re::Parent    | L4Re::Env::parent()
65   * user_factory | L4::Factory     | L4Re::Env::user_factory()
66   * log          | L4Re::Log       | L4Re::Env::log()
67   * main_thread  | L4::Thread      | L4Re::Env::main_thread()
68   * rm           | L4Re::Rm        | L4Re::Env::rm()
69   * factory      | L4::Factory     | L4Re::Env::factory()
70   * task         | L4::Task        | L4Re::Env::task()
71   * scheduler    | L4::Scheduler   | L4Re::Env::scheduler()
72   *
73   * Additional information found in the initial environment is:
74   * - First free entry in capability table
75   * - The \link l4_utcb_api UTCB \endlink area (as flex page)
76   * - First free UTCB (address in the UTCB area)
77   *
78   * \includefile{l4/re/env}
79   *
80   * For an explanation of the default task capabilites see \ref
81   * l4_default_caps_t.
82   *
83   * For the C interface refer to \ref api_l4re_env.
84   */
85  class L4_EXPORT Env
86  {
87  private:
88    l4re_env_t _env;
89  public:
90
91    /**
92     * C++ type for an entry in the initial objects array.
93     */
94    typedef l4re_env_cap_entry_t Cap_entry;
95
96    /**
97     * Returns the initial environment for the current task.
98     *
99     * \return Pointer to the initial environment class.
100     *
101     * A typical use of this function is L4Re::Env::env()->\<member\>()
102     */
103    static Env const *env() noexcept
104    { return reinterpret_cast<Env*>(l4re_global_env); }
105
106    /**
107     * Object-capability to the parent.
108     * \return Parent object-capability
109     */
110    L4::Cap<Parent> parent() const noexcept
111    { return L4::Cap<Parent>(_env.parent); }
112    /**
113     * Object-capability to the memory allocator.
114     * \return Memory allocator object-capability
115     */
116    L4::Cap<Mem_alloc> mem_alloc() const noexcept
117    { return L4::Cap<Mem_alloc>(_env.mem_alloc); }
118    /**
119     * Object-capability to the user-level object factory.
120     */
121    L4::Cap<L4::Factory> user_factory() const noexcept
122    { return L4::Cap<L4::Factory>(_env.mem_alloc); }
123    /**
124     * Object-capability to the region map.
125     * \return Region map object-capability
126     */
127    L4::Cap<Rm> rm() const noexcept
128    { return L4::Cap<Rm>(_env.rm); }
129    /**
130     * Object-capability to the logging service.
131     * \return Log object-capability
132     */
133    L4::Cap<Log> log() const noexcept
134    { return L4::Cap<Log>(_env.log); }
135    /**
136     * Object-capability of the first user thread.
137     * \return Object-capability of the first user thread.
138     */
139    L4::Cap<L4::Thread> main_thread() const noexcept
140    { return L4::Cap<L4::Thread>(_env.main_thread); }
141    /**
142     * Object-capability of the user task.
143     * \return Object-capability of the user task.
144     */
145    L4::Cap<L4::Task> task() const noexcept
146    { return L4::Cap<L4::Task>(L4RE_THIS_TASK_CAP); }
147    /**
148     * Object-capability to the factory object available to the task.
149     * \return Factory object-capability
150     */
151    L4::Cap<L4::Factory> factory() const noexcept
152    { return L4::Cap<L4::Factory>(_env.factory); }
153    /**
154     * First available capability selector.
155     * \return First capability selector.
156     *
157     * First capability selector available for use for in the application.
158     */
159    l4_cap_idx_t first_free_cap() const noexcept
160    { return _env.first_free_cap; }
161    /**
162     * UTCB area of the task.
163     * \return UTCB area
164     */
165    l4_fpage_t utcb_area() const noexcept
166    { return _env.utcb_area; }
167    /**
168     * First free UTCB.
169     * \return object-capability
170     *
171     * First free UTCB within the UTCB area available for the application to
172     * use.
173     */
174    l4_addr_t first_free_utcb() const noexcept
175    { return _env.first_free_utcb; }
176
177    /**
178     * Get a pointer to the first entry in the initial objects array.
179     * \return A pointer to the first entry in the initial objects array.
180     */
181    Cap_entry const *initial_caps() const noexcept
182    { return _env.caps; }
183
184    /**
185     * Get the Cap_entry for the object named \a name.
186     * \param name is the name of the object.
187     * \param l is the length of the name, thus \a name might not be
188     *          zero terminated.
189     * \return A pointer to the Cap_entry for the object named \a name,
190     *         or NULL if no such object was found.
191     */
192    Cap_entry const *get(char const *name, unsigned l) const noexcept
193    { return l4re_env_get_cap_l(name, l, &_env); }
194
195    /**
196     * Get the capability selector for the object named \a name.
197     * \param name is the name of the object.
198     * \param l is the length of the name, thus \a name might not be
199     *          zero terminated.
200     * \return A capability selector for the object named \a name,
201     *         or an invalid capability selector if no such object was found.
202     */
203    template< typename T >
204    L4::Cap<T> get_cap(char const *name, unsigned l) const noexcept
205    {
206      if (Cap_entry const *e = get(name, l))
207	return L4::Cap<T>(e->cap);
208
209      return L4::Cap<T>(-L4_ENOENT);
210    }
211
212    /**
213     * Get the capability selector for the object named \a name.
214     * \param name is the name of the object (zero terminated).
215     * \return A capability selector for the object named \a name,
216     *         or an invalid capability selector if no such object was found.
217     */
218    template< typename T >
219    L4::Cap<T> get_cap(char const *name) const noexcept
220    { return get_cap<T>(name, __builtin_strlen(name)); }
221
222    /**
223     * Set parent object-capability.
224     * \param c  Parent object-capability
225     */
226    void parent(L4::Cap<Parent> const &c) noexcept
227    { _env.parent = c.cap(); }
228    /**
229     * Set memory allocator object-capability.
230     * \param c  Memory allocator object-capability
231     */
232    void mem_alloc(L4::Cap<Mem_alloc> const &c) noexcept
233    { _env.mem_alloc = c.cap(); }
234    /**
235     * Set region map object-capability.
236     * \param c  Region map object-capability
237     */
238    void rm(L4::Cap<Rm> const &c) noexcept
239    { _env.rm = c.cap(); }
240    /**
241     * Set log object-capability.
242     * \param c  Log object-capability
243     */
244    void log(L4::Cap<Log> const &c) noexcept
245    { _env.log = c.cap(); }
246    /**
247     * Set object-capability of first user thread.
248     * \param c  First thread's object-capability
249     */
250    void main_thread(L4::Cap<L4::Thread> const &c) noexcept
251    { _env.main_thread = c.cap(); }
252    /**
253     * Set factory object-capability.
254     * \param c  Factory object-capability
255     */
256    void factory(L4::Cap<L4::Factory> const &c) noexcept
257    { _env.factory = c.cap(); }
258    /**
259     * Set first available capability selector.
260     * \param c First capability selector available to the application.
261     */
262    void first_free_cap(l4_cap_idx_t c) noexcept
263    { _env.first_free_cap = c; }
264    /**
265     * Set UTCB area of the task.
266     * \param utcbs  UTCB area
267     */
268    void utcb_area(l4_fpage_t utcbs) noexcept
269    { _env.utcb_area = utcbs; }
270    /**
271     * Set first free UTCB.
272     * \param u First UTCB available for the application to use.
273     */
274    void first_free_utcb(l4_addr_t u) noexcept
275    { _env.first_free_utcb = u; }
276
277    /**
278     * Get the scheduler capability for the task.
279     * \return The capability selector for the default scheduler used for this
280     *         task.
281     */
282    L4::Cap<L4::Scheduler> scheduler() const noexcept
283    { return L4::Cap<L4::Scheduler>(_env.scheduler); }
284
285    /**
286     * Set the scheduler capability.
287     * \param c is the capability to be set as scheduler.
288     */
289    void scheduler(L4::Cap<L4::Scheduler> const &c) noexcept
290    { _env.scheduler = c.cap(); }
291
292    /**
293     * Set the pointer to the first Cap_entry in the initial objects array.
294     * \param first is the first element in the array.
295     */
296    void initial_caps(Cap_entry *first) noexcept
297    { _env.caps = first; }
298  };
299};
300