4 * \brief L4::Capability class.
6 * \author Alexander Warg <alexander.warg@os.inf.tu-dresden.de>
10 * (c) 2008-2009 Author(s)
11 * economic rights: Technische Universität Dresden (Germany)
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.
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.
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>
33 #include <l4/sys/__typeinfo.h>
38 /* Forward declarations for our kernel object classes. */
47 template< typename T > class Cap;
50 * \addtogroup l4_cap_api
52 * C++ interface for capabilities:<br>
53 * <c>\#include <l4/sys/capability></c>
57 * \brief Base class for all kinds of capabilities.
58 * \attention This class is not for direct use, use L4::Cap instead.
60 * This class contains all the things that are independent of the type
61 * of the object referred by the capability.
63 * \see L4::Cap for typed capabilities.
68 struct Invalid_conversion;
74 * \brief Special value for constructing uninitialized Cap objects.
80 * \brief Invalid capability type.
84 Invalid = L4_INVALID_CAP ///< Invalid capability selector
88 * \brief Return capability selector.
89 * \return Capability selector.
91 l4_cap_idx_t cap() const throw() { return _c; }
94 * \brief Test whether capability selector is not the invalid capability
97 * \return True if capability is not invalid, false if invalid
99 bool is_valid() const throw() { return !(_c & L4_INVALID_CAP_BIT); }
101 operator Invalid_conversion * () const throw()
102 { return (Invalid_conversion*)(!(_c & L4_INVALID_CAP_BIT)); }
105 * \brief Returns flex-page of the capability selector.
106 * \param rights Rights, defaults to 'rwx'
109 l4_fpage_t fpage(unsigned rights = L4_FPAGE_RWX) const throw()
110 { return l4_obj_fpage(_c, 0, rights); }
113 * \brief Returns send base.
114 * \param grant True object should be granted.
115 * \param base Base capability selector
116 * \return Map object.
118 l4_umword_t snd_base(unsigned grant = 0,
119 l4_cap_idx_t base = L4_INVALID_CAP) const throw()
121 if (base == L4_INVALID_CAP)
123 return l4_map_obj_control(base, grant);
128 * \brief Test if two capability selectors are equal.
130 bool operator == (Cap_base const &o) const throw()
131 { return _c == o._c; }
134 * \brief Test if two capability selectors are not equal.
136 bool operator != (Cap_base const &o) const throw()
137 { return _c != o._c; }
140 * \brief Check whether a capability selector points to a valid capability.
142 * \param u UTCB of the caller
143 * \return label = 0 valid, label > 0 invalid
145 inline l4_msgtag_t validate(l4_utcb_t *u = l4_utcb()) const throw();
148 * \brief Check whether a capability selector points to a valid capability.
150 * \param u UTCB of the caller
151 * \param task Task to check the capability in
153 * \return label = 0 valid, label > 0 invalid
155 inline l4_msgtag_t validate(Cap<Task> task,
156 l4_utcb_t *u = l4_utcb()) const throw();
159 * \brief Set this selector to the invalid capability (L4_INVALID_CAP).
161 void invalidate() throw() { _c = L4_INVALID_CAP; }
164 * \brief Generate a capability from its C representation.
165 * \param c the C capability selector
167 explicit Cap_base(l4_cap_idx_t c) throw() : _c(c) {}
169 * \brief Constructor to create an invalid capability selector.
171 explicit Cap_base(Cap_type cap) throw() : _c(cap) {}
174 * \brief Initialize capability with one of the default capability selectors.
175 * \param cap Capability selector.
177 explicit Cap_base(l4_default_caps_t cap) throw() : _c(cap) {}
180 * \brief Create an uninitialized instance.
182 explicit Cap_base() throw() {}
185 * \brief The C representation of a capability selector. */
191 * \brief Capability Selector a la C++.
192 * \tparam T the type of the object the capability points to
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).
198 template< typename T >
199 class Cap : public Cap_base
202 friend class L4::Kobject;
206 * \brief Internal Constructor, use to generate a capability from a \a this
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
214 explicit Cap(T const *p) throw()
215 : Cap_base(reinterpret_cast<l4_cap_idx_t>(p)) {}
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).
223 template< typename O >
224 Cap(Cap<O> const &o) throw() : Cap_base(o.cap())
225 { register T* __t = ((O*)100); (void)__t; }
228 * \brief Constructor to create an invalid capability selector.
230 Cap(Cap_type cap) throw() : Cap_base(cap) {}
233 * \brief Initialize capability with one of the default capability selectors.
234 * \param cap Capability selector.
236 Cap(l4_default_caps_t cap) throw() : Cap_base(cap) {}
239 * \brief Initialize capability, defaults to the invalid capability selector.
240 * \param idx Capability selector.
242 explicit Cap(l4_cap_idx_t idx = L4_INVALID_CAP) throw() : Cap_base(idx) {}
245 * \brief Create an uninitialized cap selector.
247 explicit Cap(No_init_type) throw() {}
250 * \brief Move a capability to this cap slot.
251 * \param src the source capability slot.
253 * After this operation the source slot is no longer valid.
255 Cap move(Cap const &src) const
257 if (!is_valid() || !src.is_valid())
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);
267 * \brief Member access of a \a T.
269 T *operator -> () const throw() { return reinterpret_cast<T*>(_c); }
275 * \brief Specialization for \a void capabilities.
278 class Cap<void> : public Cap_base
282 explicit Cap(void const *p) throw()
283 : Cap_base(reinterpret_cast<l4_cap_idx_t>(p)) {}
286 * \brief Constructor to create an invalid capability selector.
288 Cap(Cap_type cap) throw() : Cap_base(cap) {}
291 * \brief Initialize capability with one of the default capability selectors.
292 * \param cap Capability selector.
294 Cap(l4_default_caps_t cap) throw() : Cap_base(cap) {}
297 * \brief Initialize capability, defaults to the invalid capability selector.
298 * \param idx Capability selector.
300 explicit Cap(l4_cap_idx_t idx = L4_INVALID_CAP) throw() : Cap_base(idx) {}
301 explicit Cap(No_init_type) throw() {}
304 * \brief Move a capability to this cap slot.
305 * \param src the source capability slot.
307 * After this operation the source slot is no longer valid.
309 Cap move(Cap const &src) const
311 if (!is_valid() || !src.is_valid())
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);
320 template< typename T >
321 Cap(Cap<T> const &o) throw() : Cap_base(o.cap()) {}
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.
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.
337 * L4::Cap<L4::Kobject> obj = ... ;
338 * L4::Cap<L4::Icu> icu = L4::cap_cast<L4::Icu>(obj);
341 template< typename T, typename F >
343 Cap<T> cap_cast(Cap<F> const &c) throw()
345 (void)static_cast<T const *>(reinterpret_cast<F const *>(100));
346 return Cap<T>(c.cap());
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.
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.
361 * L4::Cap<L4::Kobject> obj = ... ;
362 * L4::Cap<L4::Icu> icu = L4::cap_reinterpret_cast<L4::Icu>(obj);
365 template< typename T, typename F >
367 Cap<T> cap_reinterpret_cast(Cap<F> const &c) throw()
369 return Cap<T>(c.cap());
375 * \addtogroup l4_kernel_object_api
377 * <c>\#include <l4/sys/capability></c>
381 * \brief Disable copy of a class.
382 * \param _class is the name of the class that shall not have
383 * value copy semantics.
386 * The typical use of this is:
390 * L4_DISABLE_COPY(Non_value)
396 #define L4_DISABLE_COPY(_class) \
398 _class(_class const &); \
399 _class operator = (_class const &);
403 * \brief Disable copy and instantiation of a class.
404 * \param _class is the name of the class to be not copyable and not
407 * The typical use looks like:
411 * L4_KOBJECT_DISABLE_COPY(Type)
415 #define L4_KOBJECT_DISABLE_COPY(_class) \
418 L4_DISABLE_COPY(_class)
422 * \brief Declare a kernel object class.
423 * \param _class is the class name.
425 * The use of this macro disables copy and instantiation
426 * of the class as needed for kernel object classes derived from
429 * The typical use looks like:
431 * class Type : public L4::Kobject_t<Type, L4::Kobject>
437 #define L4_KOBJECT(_class) L4_KOBJECT_DISABLE_COPY(_class)
441 * \ingroup l4_kernel_object_api
442 * \brief Base class for all kinds of kernel objects, referred to by
445 * <c>\#include <l4/sys/capability></c>
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.
458 friend Type_info const *kobject_typeid();
463 * \brief Get a pointer to the L4Re dynamic type information
466 * \note This function is used by L4::kobject_typeid().
468 struct __Kobject_typeid { static Type_info const _m; };
471 * \brief Return capability selector.
472 * \return Capability selector.
474 * This method is for derived classes to gain access to the actual
475 * capability selector.
477 l4_cap_idx_t cap() const throw() { return _c(); }
483 * \brief Used to convert the \c this pointer to a capability selector.
485 l4_cap_idx_t _c() const throw()
486 { return reinterpret_cast<l4_cap_idx_t>(this) & L4_CAP_MASK; }
490 * \brief Decrement the in kernel reference counter for the object.
491 * \param diff is the delta that shall be subtracted from the reference
493 * \param utcb is the utcb to use for the invocation.
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.
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); }
509 Cap_base::validate(Cap<Task> task, l4_utcb_t *u) const throw()
510 { return l4_task_cap_valid_u(task.cap(), _c, u); }
513 Cap_base::validate(l4_utcb_t *u) const throw()
514 { return l4_task_cap_valid_u(L4_BASE_TASK_CAP, _c, u); }
518 #include <l4/sys/meta>
523 * \addtogroup l4_cap_api
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.
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.
541 * L4::Cap<L4::Kobject> obj = ... ;
542 * L4::Cap<L4::Icu> icu = L4::cap_dynamic_cast<L4::Icu>(obj);
545 template< typename T, typename F >
547 Cap<T> cap_dynamic_cast(Cap<F> const &c) throw()
550 return Cap<T>::Invalid;
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());
557 // FIXME: use generic checker
559 if (l4_error(mc->supports(T::kobject_proto())) > 0)
560 return Cap<T>(c.cap());
563 return Cap<T>::Invalid;