// vi:set ft=cpp: -*- Mode: C++ -*- /** * \file * Common task related definitions. */ /* * (c) 2008-2009 Adam Lackorzynski , * Alexander Warg * economic rights: Technische Universität Dresden (Germany) * * This file is part of TUD:OS and distributed under the terms of the * GNU General Public License 2. * Please see the COPYING-GPL-2 file for details. * * As a special exception, you may use this file as part of a free software * library without restriction. Specifically, if other files instantiate * templates or use macros or inline functions from this file, or you compile * this file and link it with other files to produce an executable, this * file does not by itself cause the resulting executable to be covered by * the GNU General Public License. This exception does not however * invalidate any other reasons why the executable file might be covered by * the GNU General Public License. */ #pragma once #include #include namespace L4 { /** * C++ interface of the Task kernel object, see \ref l4_task_api for * the C interface. * * The L4::Task class represents a combination of the address spaces provided * by the L4Re micro kernel. A task consists of at least a memory address space * and an object address space. On IA32 there is also an IO-port address space * associated with an L4::Task. * * L4::Task objects are created using the L4::Factory interface. * \includefile{l4/sys/task} */ class Task : public Kobject_t > { public: /** * Map resources available in the source task to a destination task. * * \param src_task Capability selector of the source task. * \param snd_fpage Send flexpage that describes an area in the address * space or object space of the source task. * \param snd_base Send base that describes an offset in the receive window * of the destination task. The lower bits contain additional * map control flags. * \param utcb UTCB pointer of the calling thread. * * \return Syscall return tag. * * This method allows for asynchronous transfer of capabilities, memory * mappings, and IO-port mappings (on IA32) from one task to another. * The destination task is the task referenced by the capability on which the * map is invoked, and the receive window is the whole address space of that * task. * * For more information on spaces and mappings, see * \ref l4re_concepts_mapping. The flexpage API is described in more detail at * \ref l4_fpage_api. */ l4_msgtag_t map(Cap const &src_task, l4_fpage_t const &snd_fpage, l4_umword_t snd_base, l4_utcb_t *utcb = l4_utcb()) noexcept { return l4_task_map_u(cap(), src_task.cap(), snd_fpage, snd_base, utcb); } /** * Revoke rights from the task. * * \param fpage Flexpage that describes an area in one capability space * of `this` task * \param map_mask Unmap mask, see #l4_unmap_flags_t * \param utcb UTCB pointer of the calling thread. * * \return Syscall return tag * * This method allows to revoke rights from the destination task. For a flex * page describing IO ports or memory, it also revokes rights from all the * tasks that got the rights delegated from the destination task (i.e., this * operation does a recursive rights revocation). If the set of rights is * empty after the revocation, the capability is unmapped. * * \note If the reference counter of a kernel object referenced in `fpage` * goes down to zero (as a result of deleting capabilities), the * deletion of the object is initiated. Objects are not destroyed until * all other kernel objects holding a reference to it drop the * reference. */ l4_msgtag_t unmap(l4_fpage_t const &fpage, l4_umword_t map_mask, l4_utcb_t *utcb = l4_utcb()) noexcept { return l4_task_unmap_u(cap(), fpage, map_mask, utcb); } /** * Revoke rights from a task. * * \param fpages An array of flexpages. Each item describes an area in * one capability space of `this` task. * \param num_fpages Number of fpages in the `fpages` array. * \param map_mask Unmap mask, see #l4_unmap_flags_t. * \param utcb UTCB pointer of the calling thread. * * Revoke rights for an array of flexpages, see #unmap for details. * * \pre The caller needs to take care that `num_fpages` is not bigger * than L4_UTCB_GENERIC_DATA_SIZE - 2. */ l4_msgtag_t unmap_batch(l4_fpage_t const *fpages, unsigned num_fpages, l4_umword_t map_mask, l4_utcb_t *utcb = l4_utcb()) noexcept { return l4_task_unmap_batch_u(cap(), fpages, num_fpages, map_mask, utcb); } /** * Release capability and delete object. * * \param obj Capability selector of the object to delete. * \param utcb UTCB pointer of the calling thread. * * \return Syscall return tag * * Initiates the deletion of the object if `obj` has the delete permission. * Objects are not destroyed until all other kernel objects holding a * reference to it drop the reference. No error will be reported if the rights * are insufficient, however, the capability is removed in all cases from the * destination task. */ l4_msgtag_t delete_obj(L4::Cap obj, l4_utcb_t *utcb = l4_utcb()) noexcept { return l4_task_delete_obj_u(cap(), obj.cap(), utcb); } /** * Release object capability. * * \param obj Capability selector of the object to release. * \param utcb UTCB pointer of the calling thread. * * \return Syscall return tag. * * This operation unmaps the capability from `this` task. * * \note If the reference counter of the kernel object referenced by `cap` * goes down to zero, the deletion of the object is initiated. Objects * are not destroyed until all other kernel objects holding a reference * to it drop the reference. */ l4_msgtag_t release_cap(L4::Cap cap, l4_utcb_t *utcb = l4_utcb()) noexcept { return l4_task_release_cap_u(this->cap(), cap.cap(), utcb); } /** * Check whether a capability is present (refers to an object). * * \param cap Valid capability to check for presence. * \utcb{utcb} * * \retval tag.label() > 0 Capability is present (refers to an object). * \retval tag.label() == 0 No capability present (void object). * * A capability is considered present when it refers to an existing * kernel object. * * \pre `cap` must be a valid capability (i.e. `cap.is_valid() == true`). * If you are unsure about the validity of your capability use * L4::Cap.validate() instead. */ l4_msgtag_t cap_valid(Cap const &cap, l4_utcb_t *utcb = l4_utcb()) noexcept { return l4_task_cap_valid_u(this->cap(), cap.cap(), utcb); } /** * Test whether two capabilities point to the same object with the same * rights. * * \param cap_a First capability selector to compare. * \param cap_b Second capability selector to compare. * \param utcb Optional: UTCB pointer of the calling thread. * * \retval tag.label() = 1: `cap_a` and `cap_b` point to the same object. * \retval tag.label() = 0: The two caps do **not** point to the same * object. */ l4_msgtag_t cap_equal(Cap const &cap_a, Cap const &cap_b, l4_utcb_t *utcb = l4_utcb()) noexcept { return l4_task_cap_equal_u(cap(), cap_a.cap(), cap_b.cap(), utcb); } /** * Add kernel-user memory. * * \param fpage Flexpage describing the virtual area the memory goes to. * \param utcb UTCP pointer of the calling thread. * * \note * The amount of kernel-user memory that can be allocated at once is limited * by the used kernel implementation. The minimum allocatable amount is one * page (`L4_PAGESIZE`). A portable implementation should not depend on * allocations greater than 16KiB to succeed. * * \return Syscall return tag */ l4_msgtag_t add_ku_mem(l4_fpage_t const &fpage, l4_utcb_t *utcb = l4_utcb()) noexcept { return l4_task_add_ku_mem_u(cap(), fpage, utcb); } }; }