3 * \brief Common thread related definitions.
6 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7 * Alexander Warg <warg@os.inf.tu-dresden.de>,
8 * Björn Döbel <doebel@os.inf.tu-dresden.de>,
9 * Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
10 * economic rights: Technische Universität Dresden (Germany)
12 * This file is part of TUD:OS and distributed under the terms of the
13 * GNU General Public License 2.
14 * Please see the COPYING-GPL-2 file for details.
16 * As a special exception, you may use this file as part of a free software
17 * library without restriction. Specifically, if other files instantiate
18 * templates or use macros or inline functions from this file, or you compile
19 * this file and link it with other files to produce an executable, this
20 * file does not by itself cause the resulting executable to be covered by
21 * the GNU General Public License. This exception does not however
22 * invalidate any other reasons why the executable file might be covered by
23 * the GNU General Public License.
27 #include <l4/sys/types.h>
28 #include <l4/sys/utcb.h>
29 #include <l4/sys/ipc.h>
32 * \defgroup l4_thread_api Thread
33 * \ingroup l4_kernel_object_api
34 * \brief Thread object.
36 * <c>\#include <l4/sys/thread.h></c>
38 * The thread class defines a thread of execution in the L4 context.
39 * Usually user-level and kernel threads are mapped 1:1 to each other.
40 * Thread kernel object are created using a Factory, see \ref l4_factory_api
41 * (l4_factory_create_thread()).
43 * An L4 thread encapsulates:
45 * - General-purpose registers
49 * - Scheduling parameters
54 * - Blocked, Runnable, Running
56 * Thread objects provide an API for
57 * - Thread configuration and manipulation
60 * The thread control functions are used to control various aspects of a
61 * thread. See l4_thread_control_start() for more information.
66 * \brief Exchange basic thread registers.
67 * \ingroup l4_thread_api
69 * \param thread Thread to manipulate
70 * \param ip New instruction pointer, use ~0UL to leave the
71 * instruction pointer unchanged
72 * \param sp New stack pointer, use ~0UL to leave the stack
74 * \param flags Ex-regs flags, see #L4_thread_ex_regs_flags
76 * \return System call return tag
78 * This method allows to manipulate and start a thread. The basic
79 * functionality is to set the instruction pointer and the stack pointer of a
80 * thread. Additionally, this method allows also to cancel ongoing IPC
81 * operations and to force the thread to raise an artificial exception (see \a
86 l4_thread_ex_regs(l4_cap_idx_t thread, l4_addr_t ip, l4_addr_t sp,
87 l4_umword_t flags) L4_NOTHROW;
91 * \ingroup l4_thread_api
94 l4_thread_ex_regs_u(l4_cap_idx_t thread, l4_addr_t ip, l4_addr_t sp,
95 l4_umword_t flags, l4_utcb_t *utcb) L4_NOTHROW;
98 * \brief Exchange basic thread registers and return previous values.
99 * \ingroup l4_thread_api
101 * \param thread Thread to manipulate
102 * \retval ip New instruction pointer, use ~0UL to leave the
103 * instruction pointer unchanged, return previous instruction
105 * \retval sp New stack pointer, use ~0UL to leave the stack
106 * pointer unchanged, returns previous stack pointer
107 * \retval flags Ex-regs flags, see #L4_thread_ex_regs_flags, return
108 * previous CPU flags of the thread.
110 * \return System call return tag
112 * This method allows to manipulate and start a thread. The basic
113 * functionality is to set the instruction pointer and the stack pointer of a
114 * thread. Additionally, this method allows also to cancel ongoing IPC
115 * operations and to force the thread to raise an artificial exception (see \a
118 * Returned values are valid only if function returns successfully.
120 L4_INLINE l4_msgtag_t
121 l4_thread_ex_regs_ret(l4_cap_idx_t thread, l4_addr_t *ip, l4_addr_t *sp,
122 l4_umword_t *flags) L4_NOTHROW;
126 * \ingroup l4_thread_api
128 L4_INLINE l4_msgtag_t
129 l4_thread_ex_regs_ret_u(l4_cap_idx_t thread, l4_addr_t *ip, l4_addr_t *sp,
130 l4_umword_t *flags, l4_utcb_t *utcb) L4_NOTHROW;
135 * \defgroup l4_thread_control_api Thread control
136 * \ingroup l4_thread_api
138 * \brief API for Thread Control method.
141 * The thread control API provides access to almost any parameter of a thread
142 * object. The API is based on a single invocation of the thread object.
143 * However, because of the huge amount of parameters, the API provides a set
144 * of functions to set specific parameters of a thread and a commit function
145 * to commit the thread control call (see l4_thread_control_commit()).
147 * A thread control operation must always start with l4_thread_control_start()
148 * and be committed with l4_thread_control_commit(). All other thread control
149 * parameter setter functions must be called between these two functions.
151 * An example for a sequence of thread control API calls can be found below.
153 * l4_utcb_t *u = l4_utcb(); <br>
154 * \link l4_thread_control_start() l4_thread_control_start(u)\endlink; <br>
155 * \link l4_thread_control_pager() l4_thread_control_pager(u, pager_cap)\endlink; <br>
156 * \link l4_thread_control_bind() l4_thread_control_bind (u, thread_utcb, task)\endlink; <br>
157 * \link l4_thread_control_commit() l4_thread_control_commit(u, thread_cap)\endlink; <br>
162 * \brief Start a thread control API sequence.
163 * \ingroup l4_thread_control_api
165 * This function starts a sequence of thread control API functions.
166 * After this functions any of following functions may be called in any order.
167 * - l4_thread_control_pager()
168 * - l4_thread_control_exc_handler()
169 * - l4_thread_control_scheduler()
170 * - l4_thread_control_bind()
171 * - l4_thread_control_alien()
172 * - l4_thread_control_ux_host_syscall() (Fiasco-UX only)
174 * To commit the changes to the thread l4_thread_control_commit() must be
177 * \note The thread control API calls store the parameters for the thread in
178 * the UTCB of the caller, this means between l4_thread_control_start()
179 * and l4_thread_control_commit() no functions that modify the UTCB
180 * contents must be called.
183 l4_thread_control_start(void) L4_NOTHROW;
187 * \ingroup l4_thread_control_api
190 l4_thread_control_start_u(l4_utcb_t *utcb) L4_NOTHROW;
193 * \brief Set the pager.
194 * \ingroup l4_thread_control_api
196 * \param pager Capability selector invoked to send a page-fault IPC.
198 * \note The pager capability selector is interpreted in the task the thread
199 * is bound to (executes in).
202 l4_thread_control_pager(l4_cap_idx_t pager) L4_NOTHROW;
206 * \ingroup l4_thread_control_api
209 l4_thread_control_pager_u(l4_cap_idx_t pager, l4_utcb_t *utcb) L4_NOTHROW;
212 * \brief Set the exception handler.
213 * \ingroup l4_thread_control_api
215 * \param exc_handler Capability selector invoked to send an exception IPC.
217 * \note The exception-handler capability selector is interpreted in the task
218 * the thread is bound to (executes in).
221 l4_thread_control_exc_handler(l4_cap_idx_t exc_handler) L4_NOTHROW;
225 * \ingroup l4_thread_control_api
228 l4_thread_control_exc_handler_u(l4_cap_idx_t exc_handler,
229 l4_utcb_t *utcb) L4_NOTHROW;
232 * \brief Set the scheduler.
233 * \ingroup l4_thread_control_api
235 * \param scheduler Capability selector invoked to send a scheduling IPC.
237 * \note The scheduler capability selector is interpreted in the task the
238 * thread is bound to (executes in).
241 l4_thread_control_scheduler(l4_cap_idx_t scheduler) L4_NOTHROW;
245 * \ingroup l4_thread_control_api
248 l4_thread_control_scheduler_u(l4_cap_idx_t scheduler, l4_utcb_t *utcb) L4_NOTHROW;
251 * \brief Bind the thread to a task.
252 * \ingroup l4_thread_control_api
254 * \param thread_utcb The address of the UTCB in the target task.
255 * \param task The target task of the thread.
257 * Binding a thread to a task has the effect that the thread
258 * afterwards executes code within that task and has access to the
259 * resources visible within that task.
261 * \note There should not be more than one thread use a UTCB to prevent
266 l4_thread_control_bind(l4_utcb_t *thread_utcb,
267 l4_cap_idx_t task) L4_NOTHROW;
271 * \ingroup l4_thread_control_api
274 l4_thread_control_bind_u(l4_utcb_t *thread_utcb,
275 l4_cap_idx_t task, l4_utcb_t *utcb) L4_NOTHROW;
278 * \brief Enable alien mode.
279 * \ingroup l4_thread_control_api
280 * \param on Boolean value defining the state of the feature.
282 * Alien mode means the thread is not allowed to invoke L4 kernel objects
283 * directly and it is also not allowed to allocate FPU state. All those
284 * operations result in an exception IPC that gets sent through the pager
285 * capability. The responsible pager can then selectively allow an object
286 * invocation or allocate FPU state for the thread.
288 * This feature can be used to attach a debugger to a thread and trace all
289 * object invocations.
292 l4_thread_control_alien(int on) L4_NOTHROW;
296 * \ingroup l4_thread_control_api
299 l4_thread_control_alien_u(l4_utcb_t *utcb, int on) L4_NOTHROW;
302 * \brief Enable pass through of native host (Linux) system calls.
303 * \ingroup l4_thread_control_api
304 * \param on Boolean value defining the state of the feature.
306 * \pre Running on Fiasco-UX
308 * This enables the thread to do host system calls. This feature is only
309 * available in Fiasco-UX and ignored in other environments.
312 l4_thread_control_ux_host_syscall(int on) L4_NOTHROW;
316 * \ingroup l4_thread_control_api
319 l4_thread_control_ux_host_syscall_u(l4_utcb_t *utcb, int on) L4_NOTHROW;
324 * \brief Commit the thread control parameters.
325 * \ingroup l4_thread_control_api
327 * \param thread Capability selector of target thread to commit to.
328 * \return system call return tag
330 L4_INLINE l4_msgtag_t
331 l4_thread_control_commit(l4_cap_idx_t thread) L4_NOTHROW;
335 * \ingroup l4_thread_control_api
337 L4_INLINE l4_msgtag_t
338 l4_thread_control_commit_u(l4_cap_idx_t thread, l4_utcb_t *utcb) L4_NOTHROW;
341 * \brief Yield current time slice.
342 * \ingroup l4_thread_api
344 * \return system call return tag
346 L4_INLINE l4_msgtag_t
347 l4_thread_yield(void) L4_NOTHROW;
350 * \brief Switch to another thread (and donate the remaining time slice).
351 * \ingroup l4_thread_api
353 * \param to_thread The thread to switch to.
355 * \return system call return tag
357 L4_INLINE l4_msgtag_t
358 l4_thread_switch(l4_cap_idx_t to_thread) L4_NOTHROW;
362 * \ingroup l4_thread_api
364 L4_INLINE l4_msgtag_t
365 l4_thread_switch_u(l4_cap_idx_t to_thread, l4_utcb_t *utcb) L4_NOTHROW;
370 * \brief Get consumed timed of thread in µs.
371 * \ingroup l4_thread_api
372 * \param thread Thread to get the consumed time from.
374 * The consumed time is returned as l4_kernel_clock_t at UTCB message
377 L4_INLINE l4_msgtag_t
378 l4_thread_stats_time(l4_cap_idx_t thread) L4_NOTHROW;
382 * \ingroup l4_thread_api
384 L4_INLINE l4_msgtag_t
385 l4_thread_stats_time_u(l4_cap_idx_t thread, l4_utcb_t *utcb) L4_NOTHROW;
389 * \brief vCPU return from event handler.
390 * \ingroup l4_thread_api
392 * \return Message tag to be used for l4_sndfpage_add() and
393 * l4_thread_vcpu_commit()
395 * The vCPU resume functionality is split in multiple functions to allow the
396 * specification of additional send-flex-pages using l4_sndfpage_add().
398 L4_INLINE l4_msgtag_t
399 l4_thread_vcpu_resume_start(void) L4_NOTHROW;
403 * \ingroup l4_thread_api
405 L4_INLINE l4_msgtag_t
406 l4_thread_vcpu_resume_start_u(l4_utcb_t *utcb) L4_NOTHROW;
409 * \brief Commit vCPU resume.
410 * \ingroup l4_thread_api
412 * \param thread Thread to be resumed, using the invalid cap can be used
413 * for the current thread.
414 * \param tag Tag to use, returned by l4_thread_vcpu_resume_start()
416 * \return System call result message tag. In extended vCPU mode and when
417 * the virtual interrupts are cleared, the return code 1 flags an incoming
418 * IPC message, whereas 0 indicates a VM exit.
420 * To resume into another address space the capability to the target task
421 * must be set in the vCPU-state (\see l4_vcpu_state_t). The task needs
422 * to be set only once, consecutive resumes to the same address space should
423 * use an invalid capability. The kernel resets the field to
424 * #L4_INVALID_CAP. To release a task use a different task or use an invalid
425 * capability with the #L4_SYSF_REPLY flag set.
427 L4_INLINE l4_msgtag_t
428 l4_thread_vcpu_resume_commit(l4_cap_idx_t thread,
429 l4_msgtag_t tag) L4_NOTHROW;
433 * \ingroup l4_thread_api
435 L4_INLINE l4_msgtag_t
436 l4_thread_vcpu_resume_commit_u(l4_cap_idx_t thread,
437 l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW;
441 * \brief Enable or disable the vCPU feature for the thread.
442 * \ingroup l4_thread_api
444 * \param thread The thread for which the vCPU feature shall be enabled or
446 * \param vcpu_state The virtual address where the kernel shall store the vCPU
447 * state in case of vCPU exits. The address must be a valid
448 * kernel-user-memory address.
449 * \return Systemcall result message tag.
451 * This function enables the vCPU feature of the \a thread if \a vcpu_state
452 * is set to a valid kernel-user-memory address, or disables the vCPU feature
453 * if \a vcpu_state is 0.
456 L4_INLINE l4_msgtag_t
457 l4_thread_vcpu_control(l4_cap_idx_t thread, l4_addr_t vcpu_state) L4_NOTHROW;
461 * \ingroup l4_thread_api
463 L4_INLINE l4_msgtag_t
464 l4_thread_vcpu_control_u(l4_cap_idx_t thread, l4_addr_t vcpu_state,
465 l4_utcb_t *utcb) L4_NOTHROW;
468 * \brief Enable or disable the extended vCPU feature for the thread.
469 * \ingroup l4_thread_api
471 * \param thread The thread for which the extended vCPU feature shall be
472 * enabled or disabled.
473 * \param vcpu_state The virtual address where the kernel shall store the vCPU
474 * state in case of vCPU exits. The address must be a valid
475 * kernel-user-memory address.
476 * \return Systemcall result message tag.
478 * The extended vCPU feature allows the use of hardware-virtualization
479 * features such as Intel's VT os AMD's SVM.
481 * This function enables the extended vCPU feature of the \a thread
482 * if \a vcpu_state is set to a valid kernel-user-memory address, or disables
483 * the vCPU feature if \a vcpu_state is 0.
486 L4_INLINE l4_msgtag_t
487 l4_thread_vcpu_control_ext(l4_cap_idx_t thread, l4_addr_t ext_vcpu_state) L4_NOTHROW;
491 * \ingroup l4_thread_api
493 L4_INLINE l4_msgtag_t
494 l4_thread_vcpu_control_ext_u(l4_cap_idx_t thread, l4_addr_t ext_vcpu_state,
495 l4_utcb_t *utcb) L4_NOTHROW;
499 * \brief Register an IRQ that will trigger upon deletion events.
500 * \ingroup l4_thread_api
502 * \param thread Thread to register IRQ for.
503 * \param irq Irq to register.
505 * \return System call result message tag.
507 L4_INLINE l4_msgtag_t
508 l4_thread_register_del_irq(l4_cap_idx_t thread, l4_cap_idx_t irq) L4_NOTHROW;
512 * \ingroup l4_thread_api
514 L4_INLINE l4_msgtag_t
515 l4_thread_register_del_irq_u(l4_cap_idx_t thread, l4_cap_idx_t irq,
516 l4_utcb_t *utcb) L4_NOTHROW;
519 * \brief Start a thread sender modifiction sequence.
520 * \ingroup l4_thread_api
522 * Add modification rules with l4_thread_modify_sender_add() and commit with
523 * l4_thread_modify_sender_commit(). Do not touch the UTCB between
524 * l4_thread_modify_sender_start() and l4_thread_modify_sender_commit().
526 * \see l4_thread_modify_sender_add
527 * \see l4_thread_modify_sender_commit
529 L4_INLINE l4_msgtag_t
530 l4_thread_modify_sender_start(void) L4_NOTHROW;
534 * \ingroup l4_thread_api
536 L4_INLINE l4_msgtag_t
537 l4_thread_modify_sender_start_u(l4_utcb_t *u) L4_NOTHROW;
540 * \brief Add a modification pattern to a sender modification sequence.
541 * \ingroup l4_thread_api
543 * \param tag Tag received from l4_thread_modify_sender_start() or
544 * previous l4_thread_modify_sender_add() calls from
546 * \param match_mask Bitmask of bits to match the label.
547 * \param match Bitmask that must be equal to the label after applying
549 * \param del_bits Bits to be deleted from the label.
550 * \param add_bits Bits to be added to the label.
552 * \return 0 on sucess, <0 on error
555 * if ((sender_label & match_mask) == match)
556 * { label = (label & ~del_bits) | add_bits; }
558 * Only the first match is applied.
560 * \see l4_thread_modify_sender_start
561 * \see l4_thread_modify_sender_commit
564 l4_thread_modify_sender_add(l4_umword_t match_mask,
566 l4_umword_t del_bits,
567 l4_umword_t add_bits,
568 l4_msgtag_t *tag) L4_NOTHROW;
572 * \ingroup l4_thread_api
575 l4_thread_modify_sender_add_u(l4_umword_t match_mask,
577 l4_umword_t del_bits,
578 l4_umword_t add_bits,
579 l4_msgtag_t *tag, l4_utcb_t *u) L4_NOTHROW;
582 * \brief Apply (commit) a sender modification sequence.
583 * \ingroup l4_thread_api
585 * \see l4_thread_modify_sender_start
586 * \see l4_thread_modify_sender_add
588 L4_INLINE l4_msgtag_t
589 l4_thread_modify_sender_commit(l4_cap_idx_t thread, l4_msgtag_t tag) L4_NOTHROW;
593 * \ingroup l4_thread_api
595 L4_INLINE l4_msgtag_t
596 l4_thread_modify_sender_commit_u(l4_cap_idx_t thread, l4_msgtag_t tag,
597 l4_utcb_t *u) L4_NOTHROW;
600 * \brief Operations on thread objects.
601 * \ingroup l4_thread_api
607 L4_THREAD_CONTROL_OP = 0UL, /**< Control operation */
608 L4_THREAD_EX_REGS_OP = 1UL, /**< Exchange registers operation */
609 L4_THREAD_SWITCH_OP = 2UL, /**< Do a thread switch */
610 L4_THREAD_STATS_OP = 3UL, /**< Thread statistics */
611 L4_THREAD_VCPU_RESUME_OP = 4UL, /**< VCPU resume */
612 L4_THREAD_REGISTER_DELETE_IRQ = 5UL, /**< Register an IPC-gate deletion IRQ */
613 L4_THREAD_MODIFY_SENDER = 6UL, /**< Modify all senders IDs that match the given pattern */
614 L4_THREAD_VCPU_CONTROL = 7UL, /**< Enable / disable VCPU feature */
615 L4_THREAD_VCPU_CONTROL_EXT = L4_THREAD_VCPU_CONTROL | 0x10000,
616 L4_THREAD_GDT_X86_OP = 0x10UL, /**< Gdt */
617 L4_THREAD_OPCODE_MASK = 0xffff, /**< Mask for opcodes */
621 * \brief Flags for the thread control operation.
622 * \ingroup l4_thread_api
626 * Values for the enabled flags need to be given in their appropriate field
628 * \see l4_thread_control
630 enum L4_thread_control_flags
632 /** The pager will be given. */
633 L4_THREAD_CONTROL_SET_PAGER = 0x0010000,
634 /** The scheduler will be given. */
635 L4_THREAD_CONTROL_SET_SCHEDULER = 0x0020000,
636 /** The task to bind the thread to will be given. */
637 L4_THREAD_CONTROL_BIND_TASK = 0x0200000,
638 /** Alien state of the thread is set. */
639 L4_THREAD_CONTROL_ALIEN = 0x0400000,
640 /** Fiasco-UX only: pass-through of host system calls is set. */
641 L4_THREAD_CONTROL_UX_NATIVE = 0x0800000,
642 /** The exception handler of the thread will be given. */
643 L4_THREAD_CONTROL_SET_EXC_HANDLER = 0x1000000,
647 * \brief Indices for the values in the message register for thread control.
648 * \ingroup l4_thread_api
652 * The values indicate the index in the message registers during
653 * thread-control operation.
655 enum L4_thread_control_mr_indices
657 L4_THREAD_CONTROL_MR_IDX_FLAGS = 0, /**< \see #L4_thread_control_flags. */
658 L4_THREAD_CONTROL_MR_IDX_PAGER = 1, /**< Index for pager cap */
659 L4_THREAD_CONTROL_MR_IDX_EXC_HANDLER = 2, /**< Index for exception handler */
660 L4_THREAD_CONTROL_MR_IDX_SCHEDULER = 3, /**< Index for scheduler */
661 L4_THREAD_CONTROL_MR_IDX_FLAG_VALS = 4, /**< Index for feature values */
662 L4_THREAD_CONTROL_MR_IDX_BIND_UTCB = 5, /**< Index for UTCB address for bind */
663 L4_THREAD_CONTROL_MR_IDX_BIND_TASK = 6, /**< Index for task flex-page for bind */
667 * \brief Flags for the thread ex-regs operation.
668 * \ingroup l4_thread_api
671 enum L4_thread_ex_regs_flags
673 L4_THREAD_EX_REGS_CANCEL = 0x10000UL, /**< Cancel ongoing IPC in the thread. */
674 L4_THREAD_EX_REGS_TRIGGER_EXCEPTION = 0x20000UL, /**< Trigger artificial exception in thread. */
678 /* IMPLEMENTATION -----------------------------------------------------------*/
680 #include <l4/sys/ipc.h>
681 #include <l4/sys/types.h>
683 L4_INLINE l4_msgtag_t
684 l4_thread_ex_regs_u(l4_cap_idx_t thread, l4_addr_t ip, l4_addr_t sp,
685 l4_umword_t flags, l4_utcb_t *utcb) L4_NOTHROW
687 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
688 v->mr[0] = L4_THREAD_EX_REGS_OP | flags;
691 return l4_ipc_call(thread, utcb, l4_msgtag(L4_PROTO_THREAD, 3, 0, 0), L4_IPC_NEVER);
694 L4_INLINE l4_msgtag_t
695 l4_thread_ex_regs_ret_u(l4_cap_idx_t thread, l4_addr_t *ip, l4_addr_t *sp,
696 l4_umword_t *flags, l4_utcb_t *utcb) L4_NOTHROW
698 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
699 l4_msgtag_t ret = l4_thread_ex_regs_u(thread, *ip, *sp, *flags, utcb);
700 if (l4_error_u(ret, utcb))
710 l4_thread_control_start_u(l4_utcb_t *utcb) L4_NOTHROW
712 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
713 v->mr[L4_THREAD_CONTROL_MR_IDX_FLAGS] = L4_THREAD_CONTROL_OP;
717 l4_thread_control_pager_u(l4_cap_idx_t pager, l4_utcb_t *utcb) L4_NOTHROW
719 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
720 v->mr[L4_THREAD_CONTROL_MR_IDX_FLAGS] |= L4_THREAD_CONTROL_SET_PAGER;
721 v->mr[L4_THREAD_CONTROL_MR_IDX_PAGER] = pager;
725 l4_thread_control_exc_handler_u(l4_cap_idx_t exc_handler,
726 l4_utcb_t *utcb) L4_NOTHROW
728 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
729 v->mr[L4_THREAD_CONTROL_MR_IDX_FLAGS] |= L4_THREAD_CONTROL_SET_EXC_HANDLER;
730 v->mr[L4_THREAD_CONTROL_MR_IDX_EXC_HANDLER] = exc_handler;
734 l4_thread_control_scheduler_u(l4_cap_idx_t scheduler, l4_utcb_t *utcb) L4_NOTHROW
736 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
737 v->mr[L4_THREAD_CONTROL_MR_IDX_FLAGS] |= L4_THREAD_CONTROL_SET_SCHEDULER;
738 v->mr[L4_THREAD_CONTROL_MR_IDX_SCHEDULER] = scheduler;
742 l4_thread_control_bind_u(l4_utcb_t *thread_utcb, l4_cap_idx_t task,
743 l4_utcb_t *utcb) L4_NOTHROW
745 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
746 v->mr[L4_THREAD_CONTROL_MR_IDX_FLAGS] |= L4_THREAD_CONTROL_BIND_TASK;
747 v->mr[L4_THREAD_CONTROL_MR_IDX_BIND_UTCB] = (l4_addr_t)thread_utcb;
748 v->mr[L4_THREAD_CONTROL_MR_IDX_BIND_TASK] = L4_ITEM_MAP;
749 v->mr[L4_THREAD_CONTROL_MR_IDX_BIND_TASK + 1] = l4_obj_fpage(task, 0, L4_FPAGE_RWX).raw;
753 l4_thread_control_alien_u(l4_utcb_t *utcb, int on) L4_NOTHROW
755 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
756 v->mr[L4_THREAD_CONTROL_MR_IDX_FLAGS] |= L4_THREAD_CONTROL_ALIEN;
757 v->mr[L4_THREAD_CONTROL_MR_IDX_FLAG_VALS] |= on ? L4_THREAD_CONTROL_ALIEN : 0;
761 l4_thread_control_ux_host_syscall_u(l4_utcb_t *utcb, int on) L4_NOTHROW
763 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
764 v->mr[L4_THREAD_CONTROL_MR_IDX_FLAGS] |= L4_THREAD_CONTROL_UX_NATIVE;
765 v->mr[L4_THREAD_CONTROL_MR_IDX_FLAG_VALS] |= on ? L4_THREAD_CONTROL_UX_NATIVE : 0;
768 L4_INLINE l4_msgtag_t
769 l4_thread_control_commit_u(l4_cap_idx_t thread, l4_utcb_t *utcb) L4_NOTHROW
772 if (l4_utcb_mr_u(utcb)->mr[L4_THREAD_CONTROL_MR_IDX_FLAGS] & L4_THREAD_CONTROL_BIND_TASK)
774 return l4_ipc_call(thread, utcb, l4_msgtag(L4_PROTO_THREAD, 6, items, 0), L4_IPC_NEVER);
778 L4_INLINE l4_msgtag_t
779 l4_thread_yield(void) L4_NOTHROW
781 l4_ipc_receive(L4_INVALID_CAP, NULL, L4_IPC_BOTH_TIMEOUT_0);
782 return l4_msgtag(0, 0, 0, 0);
785 /* Preliminary, to be changed */
786 L4_INLINE l4_msgtag_t
787 l4_thread_switch_u(l4_cap_idx_t to_thread, l4_utcb_t *utcb) L4_NOTHROW
789 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
790 v->mr[0] = L4_THREAD_SWITCH_OP;
791 return l4_ipc_call(to_thread, utcb, l4_msgtag(L4_PROTO_THREAD, 1, 0, 0), L4_IPC_NEVER);
795 L4_INLINE l4_msgtag_t
796 l4_thread_stats_time_u(l4_cap_idx_t thread, l4_utcb_t *utcb) L4_NOTHROW
798 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
799 v->mr[0] = L4_THREAD_STATS_OP;
800 return l4_ipc_call(thread, utcb, l4_msgtag(L4_PROTO_THREAD, 1, 0, 0), L4_IPC_NEVER);
803 L4_INLINE l4_msgtag_t
804 l4_thread_vcpu_resume_start_u(l4_utcb_t *utcb) L4_NOTHROW
806 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
807 v->mr[0] = L4_THREAD_VCPU_RESUME_OP;
808 return l4_msgtag(L4_PROTO_THREAD, 1, 0, 0);
811 L4_INLINE l4_msgtag_t
812 l4_thread_vcpu_resume_commit_u(l4_cap_idx_t thread,
813 l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW
815 return l4_ipc_call(thread, utcb, tag, L4_IPC_NEVER);
818 L4_INLINE l4_msgtag_t
819 l4_thread_ex_regs(l4_cap_idx_t thread, l4_addr_t ip, l4_addr_t sp,
820 l4_umword_t flags) L4_NOTHROW
822 return l4_thread_ex_regs_u(thread, ip, sp, flags, l4_utcb());
825 L4_INLINE l4_msgtag_t
826 l4_thread_ex_regs_ret(l4_cap_idx_t thread, l4_addr_t *ip, l4_addr_t *sp,
827 l4_umword_t *flags) L4_NOTHROW
829 return l4_thread_ex_regs_ret_u(thread, ip, sp, flags, l4_utcb());
833 l4_thread_control_start(void) L4_NOTHROW
835 l4_thread_control_start_u(l4_utcb());
839 l4_thread_control_pager(l4_cap_idx_t pager) L4_NOTHROW
841 l4_thread_control_pager_u(pager, l4_utcb());
845 l4_thread_control_exc_handler(l4_cap_idx_t exc_handler) L4_NOTHROW
847 l4_thread_control_exc_handler_u(exc_handler, l4_utcb());
851 l4_thread_control_scheduler(l4_cap_idx_t scheduler) L4_NOTHROW
853 l4_thread_control_scheduler_u(scheduler, l4_utcb());
858 l4_thread_control_bind(l4_utcb_t *thread_utcb, l4_cap_idx_t task) L4_NOTHROW
860 l4_thread_control_bind_u(thread_utcb, task, l4_utcb());
864 l4_thread_control_alien(int on) L4_NOTHROW
866 l4_thread_control_alien_u(l4_utcb(), on);
870 l4_thread_control_ux_host_syscall(int on) L4_NOTHROW
872 l4_thread_control_ux_host_syscall_u(l4_utcb(), on);
875 L4_INLINE l4_msgtag_t
876 l4_thread_control_commit(l4_cap_idx_t thread) L4_NOTHROW
878 return l4_thread_control_commit_u(thread, l4_utcb());
884 L4_INLINE l4_msgtag_t
885 l4_thread_switch(l4_cap_idx_t to_thread) L4_NOTHROW
887 return l4_thread_switch_u(to_thread, l4_utcb());
893 L4_INLINE l4_msgtag_t
894 l4_thread_stats_time(l4_cap_idx_t thread) L4_NOTHROW
896 return l4_thread_stats_time_u(thread, l4_utcb());
899 L4_INLINE l4_msgtag_t
900 l4_thread_vcpu_resume_start(void) L4_NOTHROW
902 return l4_thread_vcpu_resume_start_u(l4_utcb());
905 L4_INLINE l4_msgtag_t
906 l4_thread_vcpu_resume_commit(l4_cap_idx_t thread,
907 l4_msgtag_t tag) L4_NOTHROW
909 return l4_thread_vcpu_resume_commit_u(thread, tag, l4_utcb());
913 L4_INLINE l4_msgtag_t
914 l4_thread_register_del_irq_u(l4_cap_idx_t thread, l4_cap_idx_t irq,
915 l4_utcb_t *u) L4_NOTHROW
917 l4_msg_regs_t *m = l4_utcb_mr_u(u);
918 m->mr[0] = L4_THREAD_REGISTER_DELETE_IRQ;
919 m->mr[1] = l4_map_obj_control(0,0);
920 m->mr[2] = l4_obj_fpage(irq, 0, L4_CAP_FPAGE_RWS).raw;
921 return l4_ipc_call(thread, u, l4_msgtag(L4_PROTO_THREAD, 1, 1, 0), L4_IPC_NEVER);
925 L4_INLINE l4_msgtag_t
926 l4_thread_register_del_irq(l4_cap_idx_t thread, l4_cap_idx_t irq) L4_NOTHROW
928 return l4_thread_register_del_irq_u(thread, irq, l4_utcb());
932 L4_INLINE l4_msgtag_t
933 l4_thread_vcpu_control_u(l4_cap_idx_t thread, l4_addr_t vcpu_state,
934 l4_utcb_t *utcb) L4_NOTHROW
936 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
937 v->mr[0] = L4_THREAD_VCPU_CONTROL;
938 v->mr[1] = vcpu_state;
939 return l4_ipc_call(thread, utcb, l4_msgtag(L4_PROTO_THREAD, 2, 0, 0), L4_IPC_NEVER);
942 L4_INLINE l4_msgtag_t
943 l4_thread_vcpu_control(l4_cap_idx_t thread, l4_addr_t vcpu_state) L4_NOTHROW
944 { return l4_thread_vcpu_control_u(thread, vcpu_state, l4_utcb()); }
947 L4_INLINE l4_msgtag_t
948 l4_thread_vcpu_control_ext_u(l4_cap_idx_t thread, l4_addr_t ext_vcpu_state,
949 l4_utcb_t *utcb) L4_NOTHROW
951 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
952 v->mr[0] = L4_THREAD_VCPU_CONTROL_EXT;
953 v->mr[1] = ext_vcpu_state;
954 return l4_ipc_call(thread, utcb, l4_msgtag(L4_PROTO_THREAD, 2, 0, 0), L4_IPC_NEVER);
957 L4_INLINE l4_msgtag_t
958 l4_thread_vcpu_control_ext(l4_cap_idx_t thread, l4_addr_t ext_vcpu_state) L4_NOTHROW
959 { return l4_thread_vcpu_control_ext_u(thread, ext_vcpu_state, l4_utcb()); }
961 L4_INLINE l4_msgtag_t
962 l4_thread_modify_sender_start_u(l4_utcb_t *u) L4_NOTHROW
964 l4_msg_regs_t *m = l4_utcb_mr_u(u);
965 m->mr[0] = L4_THREAD_MODIFY_SENDER;
966 return l4_msgtag(L4_PROTO_THREAD, 1, 0, 0);
970 l4_thread_modify_sender_add_u(l4_umword_t match_mask,
972 l4_umword_t del_bits,
973 l4_umword_t add_bits,
974 l4_msgtag_t *tag, l4_utcb_t *u) L4_NOTHROW
976 l4_msg_regs_t *m = l4_utcb_mr_u(u);
977 unsigned w = l4_msgtag_words(*tag);
978 if (w >= L4_UTCB_GENERIC_DATA_SIZE - 4)
981 m->mr[w] = match_mask;
983 m->mr[w+2] = del_bits;
984 m->mr[w+3] = add_bits;
986 *tag = l4_msgtag(l4_msgtag_label(*tag), w + 4, 0, 0);
991 L4_INLINE l4_msgtag_t
992 l4_thread_modify_sender_commit_u(l4_cap_idx_t thread, l4_msgtag_t tag,
993 l4_utcb_t *u) L4_NOTHROW
995 return l4_ipc_call(thread, u, tag, L4_IPC_NEVER);
998 L4_INLINE l4_msgtag_t
999 l4_thread_modify_sender_start(void) L4_NOTHROW
1001 return l4_thread_modify_sender_start_u(l4_utcb());
1005 l4_thread_modify_sender_add(l4_umword_t match_mask,
1007 l4_umword_t del_bits,
1008 l4_umword_t add_bits,
1009 l4_msgtag_t *tag) L4_NOTHROW
1011 return l4_thread_modify_sender_add_u(match_mask, match,
1012 del_bits, add_bits, tag, l4_utcb());
1015 L4_INLINE l4_msgtag_t
1016 l4_thread_modify_sender_commit(l4_cap_idx_t thread, l4_msgtag_t tag) L4_NOTHROW
1018 return l4_thread_modify_sender_commit_u(thread, tag, l4_utcb());