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