]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/capability
7be6a3f53a8520db8394be5cde14d4c227ea9dc2
[l4.git] / l4 / pkg / l4sys / include / capability
1 // vim:set ft=cpp:
2 /**
3  * \file
4  * \brief  L4::Capability class.
5  *
6  * \author Alexander Warg <alexander.warg@os.inf.tu-dresden.de>
7  *
8  */
9 /*
10  * (c) 2008-2009 Author(s)
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/consts.h>
29 #include <l4/sys/types.h>
30 #include <l4/sys/kernel_object.h>
31 #include <l4/sys/task.h>
32
33 #include <l4/sys/__typeinfo.h>
34
35 namespace L4
36 {
37
38 /* Forward declarations for our kernel object classes. */
39 class Task;
40 class Thread;
41 class Factory;
42 class Irq;
43 class K_semaphore;
44 class Log;
45 class Vm;
46 class Kobject;
47
48 template< typename T > class Cap;
49
50 /**
51  * \addtogroup l4_cap_api
52  *
53  * C++ interface for capabilities:<br>
54  * <c>\#include <l4/sys/capability></c>
55  */
56 /*@{*/
57 /**
58  * \brief Base class for all kinds of capabilities.
59  * \attention This class is not for direct use, use L4::Cap instead.
60  *
61  * This class contains all the things that are independent of the type
62  * of the object referred by the capability.
63  *
64  * \see L4::Cap for typed capabilities.
65  */
66 class Cap_base
67 {
68 private:
69   struct Invalid_conversion;
70
71 public:
72   enum No_init_type
73   {
74      /**
75       * \brief Special value for constructing uninitialized Cap objects.
76       */
77      No_init
78   };
79
80   /**
81    * \brief Invalid capability type.
82    */
83   enum Cap_type
84   {
85     Invalid = L4_INVALID_CAP ///< Invalid capability selector
86   };
87
88   /**
89    * \brief Return capability selector.
90    * \return Capability selector.
91    */
92   l4_cap_idx_t cap() const throw() { return _c; }
93
94   /**
95    * \brief Test whether capability selector is not the invalid capability
96    *        selector.
97    *
98    * \return True if capability is not invalid, false if invalid
99    */
100   bool is_valid() const throw() { return !(_c & L4_INVALID_CAP_BIT); }
101
102   operator Invalid_conversion * () const throw()
103   { return (Invalid_conversion*)(!(_c & L4_INVALID_CAP_BIT)); }
104
105   /**
106    * \brief Returns flex-page of the capability selector.
107    * \param rights   Rights, defaults to 'rwx'
108    * \return flex-page
109    */
110   l4_fpage_t fpage(unsigned rights = L4_FPAGE_RWX) const throw()
111   { return l4_obj_fpage(_c, 0, rights); }
112
113   /**
114    * \brief Returns send base.
115    * \param grant  True object should be granted.
116    * \param base   Base capability selector
117    * \return Map object.
118    */
119   l4_umword_t snd_base(unsigned grant = 0,
120                        l4_cap_idx_t base = L4_INVALID_CAP) const throw()
121   {
122     if (base == L4_INVALID_CAP)
123       base = _c;
124     return l4_map_obj_control(base, grant);
125   }
126
127
128   /**
129    * \brief Test if two capability selectors are equal.
130    */
131   bool operator == (Cap_base const &o) const throw()
132   { return _c == o._c; }
133
134   /**
135    * \brief Test if two capability selectors are not equal.
136    */
137   bool operator != (Cap_base const &o) const throw()
138   { return _c != o._c; }
139
140   /**
141    * \brief Check whether a capability selector points to a valid capability.
142    *
143    * \param u     UTCB of the caller
144    * \return label = 0 valid, label > 0 invalid
145    */
146   inline l4_msgtag_t validate(l4_utcb_t *u = l4_utcb()) const throw();
147
148   /**
149    * \brief Check whether a capability selector points to a valid capability.
150    *
151    * \param u     UTCB of the caller
152    * \param task  Task to check the capability in
153    *
154    * \return label = 0 valid, label > 0 invalid
155    */
156   inline l4_msgtag_t validate(Cap<Task> task,
157                               l4_utcb_t *u = l4_utcb()) const throw();
158
159   /**
160    * \brief Set this selector to the invalid capability (L4_INVALID_CAP).
161    */
162   void invalidate() throw() { _c = L4_INVALID_CAP; }
163 protected:
164   /**
165    * \brief Generate a capability from its C representation.
166    * \param c the C capability selector
167    */
168   explicit Cap_base(l4_cap_idx_t c) throw() : _c(c) {}
169   /**
170    * \brief Constructor to create an invalid capability selector.
171    */
172   explicit Cap_base(Cap_type cap) throw() : _c(cap) {}
173
174   /**
175    * \brief Initialize capability with one of the default capability selectors.
176    * \param cap  Capability selector.
177    */
178   explicit Cap_base(l4_default_caps_t cap) throw() : _c(cap) {}
179
180   /**
181    * \brief Create an uninitialized instance.
182    */
183   explicit Cap_base() throw() {}
184
185   /**
186    * \brief The C representation of a capability selector. */
187   l4_cap_idx_t _c;
188 };
189
190
191 /**
192  * \brief Capability Selector a la C++.
193  * \tparam T the type of the object the capability points to
194  *
195  * The C++ version of a capability looks just as a pointer, in fact
196  * it is a kind of a smart pointer for our kernel objects and the
197  * objects derived from the kernel objects (L4::Kobject).
198  */
199 template< typename T >
200 class Cap : public Cap_base
201 {
202 private:
203   friend class L4::Kobject;
204
205   /**
206    * \internal
207    * \brief Internal Constructor, use to generate a capability from a \a this
208    *        pointer.
209    *
210    * \attention This constructor is only useful to generate a capability
211    *            from the \a this pointer of an objected that is an L4::Kobject.
212    *            Do \em never use this constructor for something else!
213    * \param p The \a this pointer of the Kobject or derived object
214    */
215   explicit Cap(T const *p) throw()
216   : Cap_base(reinterpret_cast<l4_cap_idx_t>(p)) {}
217
218 public:
219
220   /**
221    * \brief Create a copy from \a o, supporting implicit type casting.
222    * \param o is the source selector that shall be copied (and casted).
223    */
224   template< typename O >
225   Cap(Cap<O> const &o) throw() : Cap_base(o.cap())
226   { register T* __t = ((O*)100); (void)__t; }
227
228   /**
229    * \brief Constructor to create an invalid capability selector.
230    */
231   Cap(Cap_type cap) throw() : Cap_base(cap) {}
232
233   /**
234    * \brief Initialize capability with one of the default capability selectors.
235    * \param cap  Capability selector.
236    */
237   Cap(l4_default_caps_t cap) throw() : Cap_base(cap) {}
238
239   /**
240    * \brief Initialize capability, defaults to the invalid capability selector.
241    * \param idx  Capability selector.
242    */
243   explicit Cap(l4_cap_idx_t idx = L4_INVALID_CAP) throw() : Cap_base(idx) {}
244
245   /**
246    * \brief Create an uninitialized cap selector.
247    */
248   explicit Cap(No_init_type) throw() {}
249
250   /**
251    * \brief Move a capability to this cap slot.
252    * \param src the source capability slot.
253    *
254    * After this operation the source slot is no longer valid.
255    */
256   Cap move(Cap const &src) const
257   {
258     if (!is_valid() || !src.is_valid())
259       return *this;
260
261     l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP, src.fpage(L4_FPAGE_RWX),
262                 snd_base(L4_MAP_ITEM_GRANT));
263
264     return *this;
265   }
266
267   /**
268    * \brief Member access of a \a T.
269    */
270   T *operator -> () const throw() { return reinterpret_cast<T*>(_c); }
271 };
272
273
274 /**
275  * \internal
276  * \brief Specialization for \a void capabilities.
277  */
278 template<>
279 class Cap<void> : public Cap_base
280 {
281 public:
282
283   explicit Cap(void const *p) throw()
284   : Cap_base(reinterpret_cast<l4_cap_idx_t>(p)) {}
285
286   /**
287    * \brief Constructor to create an invalid capability selector.
288    */
289   Cap(Cap_type cap) throw() : Cap_base(cap) {}
290
291   /**
292    * \brief Initialize capability with one of the default capability selectors.
293    * \param cap  Capability selector.
294    */
295   Cap(l4_default_caps_t cap) throw() : Cap_base(cap) {}
296
297   /**
298    * \brief Initialize capability, defaults to the invalid capability selector.
299    * \param idx  Capability selector.
300    */
301   explicit Cap(l4_cap_idx_t idx = L4_INVALID_CAP) throw() : Cap_base(idx) {}
302   explicit Cap(No_init_type) throw() {}
303
304   /**
305    * \brief Move a capability to this cap slot.
306    * \param src the source capability slot.
307    *
308    * After this operation the source slot is no longer valid.
309    */
310   Cap move(Cap const &src) const
311   {
312     if (!is_valid() || !src.is_valid())
313       return *this;
314
315     l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP, src.fpage(L4_FPAGE_RWX),
316                 snd_base(L4_MAP_ITEM_GRANT));
317
318     return *this;
319   }
320
321   template< typename T >
322   Cap(Cap<T> const &o) throw() : Cap_base(o.cap()) {}
323 };
324
325 /**
326  * \brief static_cast for capabilities.
327  * \param T is the target type of the capability
328  * \param F is the source type (and is usually implicitly set)
329  * \param c is the source capability that shall be casted
330  * \return A capability typed to the interface \a T.
331  *
332  * The use of this cast operator is similar to the static_cast<>() for
333  * C++ pointers.  It does the same type checking and adjustment like
334  * C++ does on pointers.
335  *
336  * Example code:
337  * \code
338  * L4::Cap<L4::Kobject> obj = ... ;
339  * L4::Cap<L4::Icu> icu = L4::cap_cast<L4::Icu>(obj);
340  * \endcode
341  */
342 template< typename T, typename F >
343 inline
344 Cap<T> cap_cast(Cap<F> const &c) throw()
345 {
346   (void)static_cast<T const *>(reinterpret_cast<F const *>(100));
347   return Cap<T>(c.cap());
348 }
349
350 /**
351  * \brief reinterpret_cast for capabilities.
352  * \param T is the target type of the capability
353  * \param F is the source type (and is usually implicitly set)
354  * \param c is the source capability that shall be casted
355  * \return A capability typed to the interface \a T. 
356  *
357  * The use of this cast operator is similar to the reinterpret_cast<>() for
358  * C++ pointers.  It does not do any type checking or type adjustment.
359  *
360  * Example code:
361  * \code
362  * L4::Cap<L4::Kobject> obj = ... ;
363  * L4::Cap<L4::Icu> icu = L4::cap_reinterpret_cast<L4::Icu>(obj);
364  * \endcode
365  */
366 template< typename T, typename F >
367 inline
368 Cap<T> cap_reinterpret_cast(Cap<F> const &c) throw()
369 {
370   return Cap<T>(c.cap());
371 }
372
373 /*@}*/
374
375 /**
376  * \addtogroup l4_kernel_object_api
377  *
378  * <c>\#include <l4/sys/capability></c>
379  */
380 /*@{*/
381 /**
382  * \brief Disable copy of a class.
383  * \param _class is the name of the class that shall not have
384  *               value copy semantics.
385  *
386  *
387  * The typical use of this is:
388  * \code
389  * class Non_value
390  * {
391  *   L4_DISABLE_COPY(Non_value)
392  *
393  *   ...
394  * }
395  * \endcode
396  */
397 #define L4_DISABLE_COPY(_class)         \
398   private:                              \
399     _class(_class const &);             \
400     _class operator = (_class const &);
401
402
403 /**
404  * \brief Disable copy and instantiation of a class.
405  * \param _class is the name of the class to be not copyable and not
406  *               instantiatable.
407  *
408  * The typical use looks like:
409  * \code
410  * class Type
411  * {
412  *   L4_KOBJECT_DISABLE_COPY(Type)
413  * };
414  * \endcode
415  */
416 #define L4_KOBJECT_DISABLE_COPY(_class) \
417   protected:                            \
418     _class();                           \
419   L4_DISABLE_COPY(_class)
420
421
422 /**
423  * \brief Declare a kernel object class.
424  * \param _class is the class name.
425  *
426  * The use of this macro disables copy and instantiation
427  * of the class as needed for kernel object classes derived from
428  * L4::Kobject.
429  *
430  * The typical use looks like:
431  * \code
432  * class Type : public L4::Kobject_t<Type, L4::Kobject>
433  * {
434  *   L4_KOBJECT(Type)
435  * };
436  * \endcode
437  */
438 #define L4_KOBJECT(_class) L4_KOBJECT_DISABLE_COPY(_class)
439
440 /**
441  * \internal
442  * \brief L4Re dynamic type information for \c void.
443  */
444 static Type_info const kobject__m = { L4_KOBJECT_META_RTTI(void), 0, 0, 0 };
445
446 /**
447  * \ingroup l4_kernel_object_api
448  * \brief Base class for all kinds of kernel objects, referred to by
449  *        capabilities.
450  *
451  * <c>\#include <l4/sys/capability></c>
452  *
453  * \attention Objects derived from Kobject \em must never add any data to
454  *            those objects. Kobjects can act only as proxy object
455  *            for encapsulating object invocations.
456  */
457 class Kobject
458 {
459   L4_KOBJECT(Kobject)
460
461 private:
462
463   template<typename T>
464   friend Type_info const *kobject_typeid();
465
466   /**
467    * \internal
468    * \brief Get a pointer to the L4Re dynamic type information
469    *        for this class.
470    *
471    * \note This function is used by L4::kobject_typeid().
472    */
473   static Type_info const *__kobject_typeid()
474   { return &kobject__m; }
475
476 protected:
477   /**
478    * \brief Return capability selector.
479    * \return Capability selector.
480    *
481    * This method is for derived classes to gain access to the actual
482    * capability selector.
483    */
484   l4_cap_idx_t cap() const throw() { return _c(); }
485
486 private:
487
488   /**
489    * \internal
490    * \brief Used to convert the \c this pointer to a capability selector.
491    */
492   l4_cap_idx_t _c() const throw()
493   { return reinterpret_cast<l4_cap_idx_t>(this) & L4_CAP_MASK; }
494
495 public:
496   /**
497    * \brief Decrement the in kernel reference counter for the object.
498    * \param diff is the delta that shall be subtracted from the reference
499    *             count.
500    * \param utcb is the utcb to use for the invocation.
501    *
502    * This function is intended for servers to be able to remove the servers
503    * own capability from the counted references.  This leads to the semantics
504    * that the kernel will delete the object even if the capability of the
505    * server is valid.  The server can detect the deletion by polling its
506    * capabilities or by using the IPC-gate deletion IRQs.  And to cleanup
507    * if the clients dropped the last reference (capability) to the object.
508    */
509   l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
510   { return l4_kobject_dec_refcnt_u(cap(), diff, utcb); }
511 };
512
513 /*@}*/
514
515 inline l4_msgtag_t
516 Cap_base::validate(Cap<Task> task, l4_utcb_t *u) const throw()
517 { return l4_task_cap_valid_u(task.cap(), _c, u);  }
518
519 inline l4_msgtag_t
520 Cap_base::validate(l4_utcb_t *u) const throw()
521 { return l4_task_cap_valid_u(L4_BASE_TASK_CAP, _c, u);  }
522
523
524 }; // namespace L4
525
526 #include <l4/sys/meta>
527
528 namespace L4 {
529
530 /**
531  * \addtogroup l4_cap_api
532  */
533 /*@{*/
534 /**
535  * \brief dynamic_cast for capabilities.
536  * \param T is the target type of the capability
537  * \param F is the source type (and is usually implicitly set)
538  * \param c is the source capability that shall be casted
539  * \return A capability typed to the interface \a T.  If the object does not
540  *         support the target interface \a T or does not support the
541  *         L4::Meta interface the result is the invalid capability selector.
542  *
543  * The use of this cast operator is similar to the dynamic_cast<>() for
544  * C++ pointers.  It also induces overhead, because it uses the meta interface
545  * (L4::Meta) to do runtime type checking.
546  *
547  * Example code:
548  * \code
549  * L4::Cap<L4::Kobject> obj = ... ;
550  * L4::Cap<L4::Icu> icu = L4::cap_dynamic_cast<L4::Icu>(obj);
551  * \endcode
552  */
553 template< typename T, typename F >
554 inline
555 Cap<T> cap_dynamic_cast(Cap<F> const &c) throw()
556 {
557   if (!c.is_valid())
558     return Cap<T>::Invalid;
559
560   Cap<Meta> mc = cap_reinterpret_cast<Meta>(c);
561   Type_info const *m = kobject_typeid<T>();
562   if (m->proto() && l4_error(mc->supports(m->proto())) > 0)
563     return Cap<T>(c.cap());
564
565   // FIXME: use generic checker
566 #if 0
567   if (l4_error(mc->supports(T::kobject_proto())) > 0)
568     return Cap<T>(c.cap());
569 #endif
570
571   return Cap<T>::Invalid;
572 }
573
574 /*@}*/
575 }