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. */
48 template< typename T > class Cap;
51 * \addtogroup l4_cap_api
53 * C++ interface for capabilities:<br>
54 * <c>\#include <l4/sys/capability></c>
58 * \brief Base class for all kinds of capabilities.
59 * \attention This class is not for direct use, use L4::Cap instead.
61 * This class contains all the things that are independent of the type
62 * of the object referred by the capability.
64 * \see L4::Cap for typed capabilities.
69 struct Invalid_conversion;
75 * \brief Special value for constructing uninitialized Cap objects.
81 * \brief Invalid capability type.
85 Invalid = L4_INVALID_CAP ///< Invalid capability selector
89 * \brief Return capability selector.
90 * \return Capability selector.
92 l4_cap_idx_t cap() const throw() { return _c; }
95 * \brief Test whether capability selector is not the invalid capability
98 * \return True if capability is not invalid, false if invalid
100 bool is_valid() const throw() { return !(_c & L4_INVALID_CAP_BIT); }
102 operator Invalid_conversion * () const throw()
103 { return (Invalid_conversion*)(!(_c & L4_INVALID_CAP_BIT)); }
106 * \brief Returns flex-page of the capability selector.
107 * \param rights Rights, defaults to 'rwx'
110 l4_fpage_t fpage(unsigned rights = L4_FPAGE_RWX) const throw()
111 { return l4_obj_fpage(_c, 0, rights); }
114 * \brief Returns send base.
115 * \param grant True object should be granted.
116 * \param base Base capability selector
117 * \return Map object.
119 l4_umword_t snd_base(unsigned grant = 0,
120 l4_cap_idx_t base = L4_INVALID_CAP) const throw()
122 if (base == L4_INVALID_CAP)
124 return l4_map_obj_control(base, grant);
129 * \brief Test if two capability selectors are equal.
131 bool operator == (Cap_base const &o) const throw()
132 { return _c == o._c; }
135 * \brief Test if two capability selectors are not equal.
137 bool operator != (Cap_base const &o) const throw()
138 { return _c != o._c; }
141 * \brief Check whether a capability selector points to a valid capability.
143 * \param u UTCB of the caller
144 * \return label = 0 valid, label > 0 invalid
146 inline l4_msgtag_t validate(l4_utcb_t *u = l4_utcb()) const throw();
149 * \brief Check whether a capability selector points to a valid capability.
151 * \param u UTCB of the caller
152 * \param task Task to check the capability in
154 * \return label = 0 valid, label > 0 invalid
156 inline l4_msgtag_t validate(Cap<Task> task,
157 l4_utcb_t *u = l4_utcb()) const throw();
160 * \brief Set this selector to the invalid capability (L4_INVALID_CAP).
162 void invalidate() throw() { _c = L4_INVALID_CAP; }
165 * \brief Generate a capability from its C representation.
166 * \param c the C capability selector
168 explicit Cap_base(l4_cap_idx_t c) throw() : _c(c) {}
170 * \brief Constructor to create an invalid capability selector.
172 explicit Cap_base(Cap_type cap) throw() : _c(cap) {}
175 * \brief Initialize capability with one of the default capability selectors.
176 * \param cap Capability selector.
178 explicit Cap_base(l4_default_caps_t cap) throw() : _c(cap) {}
181 * \brief Create an uninitialized instance.
183 explicit Cap_base() throw() {}
186 * \brief The C representation of a capability selector. */
192 * \brief Capability Selector a la C++.
193 * \tparam T the type of the object the capability points to
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).
199 template< typename T >
200 class Cap : public Cap_base
203 friend class L4::Kobject;
207 * \brief Internal Constructor, use to generate a capability from a \a this
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
215 explicit Cap(T const *p) throw()
216 : Cap_base(reinterpret_cast<l4_cap_idx_t>(p)) {}
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).
224 template< typename O >
225 Cap(Cap<O> const &o) throw() : Cap_base(o.cap())
226 { register T* __t = ((O*)100); (void)__t; }
229 * \brief Constructor to create an invalid capability selector.
231 Cap(Cap_type cap) throw() : Cap_base(cap) {}
234 * \brief Initialize capability with one of the default capability selectors.
235 * \param cap Capability selector.
237 Cap(l4_default_caps_t cap) throw() : Cap_base(cap) {}
240 * \brief Initialize capability, defaults to the invalid capability selector.
241 * \param idx Capability selector.
243 explicit Cap(l4_cap_idx_t idx = L4_INVALID_CAP) throw() : Cap_base(idx) {}
246 * \brief Create an uninitialized cap selector.
248 explicit Cap(No_init_type) throw() {}
251 * \brief Move a capability to this cap slot.
252 * \param src the source capability slot.
254 * After this operation the source slot is no longer valid.
256 Cap move(Cap const &src) const
258 if (!is_valid() || !src.is_valid())
261 l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP, src.fpage(L4_FPAGE_RWX),
262 snd_base(L4_MAP_ITEM_GRANT));
268 * \brief Member access of a \a T.
270 T *operator -> () const throw() { return reinterpret_cast<T*>(_c); }
276 * \brief Specialization for \a void capabilities.
279 class Cap<void> : public Cap_base
283 explicit Cap(void const *p) throw()
284 : Cap_base(reinterpret_cast<l4_cap_idx_t>(p)) {}
287 * \brief Constructor to create an invalid capability selector.
289 Cap(Cap_type cap) throw() : Cap_base(cap) {}
292 * \brief Initialize capability with one of the default capability selectors.
293 * \param cap Capability selector.
295 Cap(l4_default_caps_t cap) throw() : Cap_base(cap) {}
298 * \brief Initialize capability, defaults to the invalid capability selector.
299 * \param idx Capability selector.
301 explicit Cap(l4_cap_idx_t idx = L4_INVALID_CAP) throw() : Cap_base(idx) {}
302 explicit Cap(No_init_type) throw() {}
305 * \brief Move a capability to this cap slot.
306 * \param src the source capability slot.
308 * After this operation the source slot is no longer valid.
310 Cap move(Cap const &src) const
312 if (!is_valid() || !src.is_valid())
315 l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP, src.fpage(L4_FPAGE_RWX),
316 snd_base(L4_MAP_ITEM_GRANT));
321 template< typename T >
322 Cap(Cap<T> const &o) throw() : Cap_base(o.cap()) {}
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.
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.
338 * L4::Cap<L4::Kobject> obj = ... ;
339 * L4::Cap<L4::Icu> icu = L4::cap_cast<L4::Icu>(obj);
342 template< typename T, typename F >
344 Cap<T> cap_cast(Cap<F> const &c) throw()
346 (void)static_cast<T const *>(reinterpret_cast<F const *>(100));
347 return Cap<T>(c.cap());
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.
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.
362 * L4::Cap<L4::Kobject> obj = ... ;
363 * L4::Cap<L4::Icu> icu = L4::cap_reinterpret_cast<L4::Icu>(obj);
366 template< typename T, typename F >
368 Cap<T> cap_reinterpret_cast(Cap<F> const &c) throw()
370 return Cap<T>(c.cap());
376 * \addtogroup l4_kernel_object_api
378 * <c>\#include <l4/sys/capability></c>
382 * \brief Disable copy of a class.
383 * \param _class is the name of the class that shall not have
384 * value copy semantics.
387 * The typical use of this is:
391 * L4_DISABLE_COPY(Non_value)
397 #define L4_DISABLE_COPY(_class) \
399 _class(_class const &); \
400 _class operator = (_class const &);
404 * \brief Disable copy and instantiation of a class.
405 * \param _class is the name of the class to be not copyable and not
408 * The typical use looks like:
412 * L4_KOBJECT_DISABLE_COPY(Type)
416 #define L4_KOBJECT_DISABLE_COPY(_class) \
419 L4_DISABLE_COPY(_class)
423 * \brief Declare a kernel object class.
424 * \param _class is the class name.
426 * The use of this macro disables copy and instantiation
427 * of the class as needed for kernel object classes derived from
430 * The typical use looks like:
432 * class Type : public L4::Kobject_t<Type, L4::Kobject>
438 #define L4_KOBJECT(_class) L4_KOBJECT_DISABLE_COPY(_class)
442 * \brief L4Re dynamic type information for \c void.
444 static Type_info const kobject__m = { L4_KOBJECT_META_RTTI(void), 0, 0, 0 };
447 * \ingroup l4_kernel_object_api
448 * \brief Base class for all kinds of kernel objects, referred to by
451 * <c>\#include <l4/sys/capability></c>
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.
464 friend Type_info const *kobject_typeid();
468 * \brief Get a pointer to the L4Re dynamic type information
471 * \note This function is used by L4::kobject_typeid().
473 static Type_info const *__kobject_typeid()
474 { return &kobject__m; }
478 * \brief Return capability selector.
479 * \return Capability selector.
481 * This method is for derived classes to gain access to the actual
482 * capability selector.
484 l4_cap_idx_t cap() const throw() { return _c(); }
490 * \brief Used to convert the \c this pointer to a capability selector.
492 l4_cap_idx_t _c() const throw()
493 { return reinterpret_cast<l4_cap_idx_t>(this) & L4_CAP_MASK; }
497 * \brief Decrement the in kernel reference counter for the object.
498 * \param diff is the delta that shall be subtracted from the reference
500 * \param utcb is the utcb to use for the invocation.
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.
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); }
516 Cap_base::validate(Cap<Task> task, l4_utcb_t *u) const throw()
517 { return l4_task_cap_valid_u(task.cap(), _c, u); }
520 Cap_base::validate(l4_utcb_t *u) const throw()
521 { return l4_task_cap_valid_u(L4_BASE_TASK_CAP, _c, u); }
526 #include <l4/sys/meta>
531 * \addtogroup l4_cap_api
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.
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.
549 * L4::Cap<L4::Kobject> obj = ... ;
550 * L4::Cap<L4::Icu> icu = L4::cap_dynamic_cast<L4::Icu>(obj);
553 template< typename T, typename F >
555 Cap<T> cap_dynamic_cast(Cap<F> const &c) throw()
558 return Cap<T>::Invalid;
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());
565 // FIXME: use generic checker
567 if (l4_error(mc->supports(T::kobject_proto())) > 0)
568 return Cap<T>(c.cap());
571 return Cap<T>::Invalid;