]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/abi/l4_types.cpp
6c629e1945df4e21042868c81d44618e11ff8a71
[l4.git] / kernel / fiasco / src / abi / l4_types.cpp
1 /*
2  * arch. independent L4 Types
3  */
4
5 INTERFACE:
6
7 #include "types.h"
8 #include "l4_fpage.h"
9 #include "l4_buf_desc.h"
10 #include "l4_error.h"
11
12 typedef Address Local_id;
13
14 class Utcb;
15
16 /**
17  * A reference to a kernel object (capability selector),
18  * as passed from user level.
19  *
20  * A capability selector contains an index into the capability table/object
21  * space of a task.  The index is usually stored in the most significant bits
22  * of the binary representation. The twelve least significant bits are used to
23  * to denote the type of operation that shall be invoked and also so flags for
24  * special capabilities, such as the invalid cap, the reply capability, or the
25  * self capability.
26  *
27  * Generally all operations on kernel objects are modelled as message passing
28  * primitives that consist of two phases, the send phase and the receive phase.
29  * However, both phases are optional and come in slightly different flavors.
30  * \see L4_obj_ref::Operation.
31  * The terms send and receive are from the invokers point of view.  This means,
32  * a client doing RPC needs a send for sending the requested operation an
33  * parameters and a receive to receive the return code of the RPC.
34  */
35 class L4_obj_ref
36 {
37 public:
38   /**
39    * Operation codes, stored in the four least significant bits of a capability
40    * selector.
41    */
42   enum Operation
43   {
44     /// A no-op on the capability (undefined from user level).
45     None = 0,
46
47     /**
48      * \deprecated Use #Ipc_call_ipc.
49      * Deprecated call code, do not use this operation code.
50      */
51     Ipc_call = 0,
52
53     /**
54      * Set this bit to include a send phase.
55      *
56      * In the case of a send phase, the message is send to the object
57      * denoted by either the capability selector (cap()), the reply capability
58      * (if #Ipc_reply is also set), or to the thread itself (if the cap is the
59      * special self capability).
60      */
61     Ipc_send = 1,
62
63     /**
64      * Set this bit to include a receive phase.
65      *
66      * During the receive phase the caller waits for a message from either a
67      * specific sender (closed wait) or from any possible sender
68      * (#Ipc_open_wait) that has a capability to send messages to the invoker.
69      */
70     Ipc_recv = 2,
71
72     /**
73      * Set this bit to denote an open-wait receive phase.
74      *
75      * An open wait means that the invoker shall wait for a message from any
76      * sender that has a capability to send messages to the invoker.  In this
77      * case the index (cap()) in the capability selector are ignored for the
78      * receive phase.
79      */
80     Ipc_open_wait = 4,
81
82     /**
83      * Set this bit to make the send phase a reply.
84      *
85      * A reply operation uses the implicit reply capability that is stored
86      * in per thread storage and can be used only once. The reply capability
87      * also vanishes in the case of an abort due to the caller or a newly
88      * received call operation by the same thread.
89      * \see #Ipc_send.
90      */
91     Ipc_reply = 8,
92
93     /**
94      * Denotes a wait operation. (#Ipc_recv | #Ipc_open_wait).
95      *
96      * The wait operation is usually used by servers to implement remote
97      * objects.
98      */
99     Ipc_wait           = Ipc_open_wait | Ipc_recv,
100
101     /**
102      * Denotes a combination of a send and a wait operation (#Ipc_send |
103      * #Ipc_recv | #Ipc_open_wait).
104      *
105      * \note this is not used for usual RPC, see #Ipc_reply_and_wait for that.
106      */
107     Ipc_send_and_wait  = Ipc_open_wait | Ipc_send | Ipc_recv,
108
109     /**
110      * Denotes a reply and wait operation (#Ipc_send | #Ipc_reply | #Ipc_recv |
111      * #Ipc_open_wait).
112      *
113      * This operation is usually used to send replies to RPC requests.
114      */
115     Ipc_reply_and_wait = Ipc_open_wait | Ipc_send | Ipc_recv | Ipc_reply,
116
117     /**
118      * Denotes a call operation (#Ipc_send | #Ipc_recv).
119      *
120      * A call is usually used by a client to invoke an operation on a remote
121      * object and wait for a result. The call operation establishes the
122      * implicit reply capability for the partner thread (see #Ipc_reply)
123      * and enables the implementation of an object to respond to an invocation
124      * without knowledge of the invoker thread.
125      */
126     Ipc_call_ipc       = Ipc_send | Ipc_recv,
127   };
128
129   /**
130    * Special capability selectors (e.g., Invalid cap).
131    */
132   enum Special
133   {
134     /**
135      * Invalid capability selector.
136      */
137     Invalid      = 1UL << 11UL,
138
139     /**
140      * Bit that flags a capability selector as special.
141      */
142     Special_bit  = 1UL << 11UL,
143
144     /**
145      * Value for the self capability selector. This means, the invoking thread
146      * references itself.
147      */
148     Self         = (~0UL) << 11UL,
149
150     /**
151      * Mask for getting all bits of special capabilities.
152      */
153     Special_mask = (~0UL) << 11UL,
154   };
155
156   enum
157   {
158     Cap_shift = 12UL
159   };
160
161   /**
162    * Create a special capability selector from \a s.
163    * \param s which special cap selector shall be created
164    *          (see L4_obj_ref::Special).
165    *
166    * Special capability selectors are the invalid capability and the self
167    * Capability.  All special capability selectors must have the #Special_bit
168    * set.
169    */
170   L4_obj_ref(Special s = Invalid) : _raw(s) {}
171
172   /**
173    * Create a capability selector from it's binary representation.
174    * \param raw the raw binary representation of a capability selector. As
175    *            passed from user land.
176    */
177   static L4_obj_ref from_raw(Mword raw) { return L4_obj_ref(true, raw); }
178
179   /**
180    * Is the capability selector a valid capability (no special capability).
181    * \return true if the capability selector is a valid index into the
182    *         capability table, or false if the selector is a special
183    *         capability.
184    */
185   bool valid() const { return !(_raw & Special_bit); }
186
187   /**
188    * Is the capability selector a special capability (i.e., not an index
189    * into the capability table).
190    * \return true if the capability selector denotes a special capability
191    *         (see L4_obj_ref::Special), or false if this capability is a
192    *         valid index into a capability table.
193    *
194    */
195   bool special() const { return _raw & Special_bit; }
196
197   /**
198    * Is this capability selector the special \a self capability.
199    * \return true if this capability is the special self capability for the
200    *         invoking thread.
201    */
202   bool self() const { return special(); }
203
204   /**
205    * Get the value of a special capability.
206    * \pre special() == true
207    * \return the value of a special capability selector, see
208    *         L4_obj_ref::Special.
209    */
210   Special special_cap() const { return Special(_raw & Special_mask); }
211   //bool self() const { return (_raw & Invalid_mask) == Self; }
212
213   /**
214    * Does the operation contain a receive phase?
215    * \return true if the operation encoded in the capability selector
216    *              comprises a receive phase, see #L4_obj_ref::Ipc_recv.
217    */
218   unsigned have_recv() const { return _raw & Ipc_recv; }
219
220   /**
221    * Get the index into the capability table.
222    * \pre valid() == true
223    * \return The index into the capability table stored in the capability
224    *         selector (i.e., the most significant bits of the selector).
225    */
226   unsigned long cap() const { return _raw >> 12; }
227
228   /**
229    * Get the operation stored in this selector (see L4_obj_ref::Operation).
230    * \return The operation encoded in the lower 4 bits of the capability
231    *         selector, see L4_obj_ref::Operation.
232    */
233   Operation op() const { return Operation(_raw & 0xf); }
234
235   /**
236    * Get the raw binary representation of this capability selector.
237    * \return the binary representation of this cap selector.
238    */
239   Mword raw() const { return _raw; }
240
241   /**
242    * Create a valid capability selector for the shifted cap-table index
243    * and the operation.
244    * \param cap the shifted (<< #Cap_shift) capability-table index.
245    * \param op the operation to be encoded in bits 0..3.
246    */
247   explicit L4_obj_ref(Mword cap, Operation op = None) : _raw(cap | op) {}
248
249   /**
250    * Create a capability selector (index 0) with the given operation.
251    * \param op the operation to be encoded into the capability selector,
252    *        see L4_obj_ref::Operation.
253    */
254   L4_obj_ref(Operation op) : _raw(op) {}
255
256   /**
257    * Compare two capability selectors for equality.
258    * \param o the right hand side for te comparison.
259    * \note Capability selectors are compared by their binary representation.
260    */
261   bool operator == (L4_obj_ref const &o) const { return _raw == o._raw; }
262
263 private:
264   L4_obj_ref(bool, Mword raw) : _raw(raw) {}
265   Mword _raw;
266 };
267
268
269 /**
270  * Flags for unmap operations.
271  */
272 class L4_map_mask
273 {
274 public:
275
276   /**
277    * Create a from binary representation.
278    * \param raw the binary representation, as passed from user level.
279    */
280   explicit L4_map_mask(Mword raw = 0) : _raw(raw) {}
281
282   /**
283    * Get the flags for a full unmap.
284    * \return A L4_map_mask for doing a full unmap operation.
285    */
286   static L4_map_mask full() { return L4_map_mask(0xc0000002); }
287
288   /**
289    * Get the raw binary representation for the map mask.
290    * \return the binary value of the flags.
291    */
292   Mword raw() const { return _raw; }
293
294   /**
295    * Unmap from the calling Task too.
296    * \return true if the caller wishes to unmap from its own address space too.
297    */
298   Mword self_unmap() const { return _raw & 0x80000000; }
299
300   /**
301    * Shall the unmap delete the object if allowed?
302    * \return true if the unmap operation shall also delete the kernel
303    * object if permitted to the caller.
304    */
305   Mword do_delete() const { return _raw & 0x40000000; }
306
307 private:
308   Mword _raw;
309 };
310
311
312 /**
313  * Description of a message to the kernel or other thread.
314  *
315  * A message tag determines the number of untyped message words (words()), the
316  * number of typed message items (items(), L4_msg_item), some flags, and a
317  * protocol ID.  The number of typed and untyped items in the UTCB's message
318  * registers, as well as the flags, control the kernels message passing
319  * mechanism.  The protocol ID is not interpreted by the message passing
320  * itself, however is interpreted by the receiving object itself.  In thread to
321  * thread IPC the all contents besides the flags are copied from the sender to
322  * the receiver. The flags on the receiver side contain some information about
323  * the operation itself.
324  *
325  * The untyped message words are copied to the receiving object/thread
326  * uninterpreted. The typed items directly following the untyped words in
327  * the message registers are interpreted by the message passing and contain,
328  * for example, map items for memory or kernel objects (see L4_msg_item,
329  * L4_fpage).
330  */
331 class L4_msg_tag
332 {
333 public:
334   /**
335    * Flags in the message tag.
336    *
337    * The input flags control the send phase of an IPC operation. Flags might
338    * have a different semantics in the returned message tag, the result of an
339    * IPC operation, see L4_msg_tag::Output_flags. However, the #Transfer_fpu
340    * and #Schedule flags are passed to the receiver.
341    */
342   enum Flags
343   {
344     /**
345      * The sender is transferring the state of the floating-point unit (FPU)
346      * as part of the message.
347      * \note The receiver needs to agree with that by setting
348      *       L4_buf_desc::Inherit_fpu in its buffer descriptor register (BDR).
349      * \note This flag is passed through to the receiver.
350      */
351     Transfer_fpu = 0x1000,
352
353     /**
354      * The sender does not want to donate its remaining time-slice to the
355      * receiver (partner) thread.
356      * \note This flag is passed on to the receiver.
357      */
358     Schedule     = 0x2000,
359
360     /**
361      * The sender wants to propagate an incoming call operation to a different
362      * thread.
363      * \note Not implemented in Fiasco.OC.
364      *
365      * Propagation means that the reply capability shall be passed on to the
366      * receiver of this message to enable a direct reply.
367      */
368     Propagate    = 0x4000, // snd only flag
369   };
370
371   /**
372    * Result flags for IPC operations.
373    *
374    * These flags are dedicated return values for an IPC operation.
375    */
376   enum Output_flags
377   {
378     /**
379      * The IPC operation did not succeed, the detailed error code
380      * is in the error register in the UTCB.
381      */
382     Error        = 0x8000,
383
384     /**
385      * The IPC operation did cross CPU boundaries.
386      */
387     X_cpu        = 0x4000,
388
389     /**
390      * Combination of flags that are not pass through.
391      */
392     Rcv_flags    = Error | X_cpu,
393   };
394
395   /**
396    * Protocol IDs that are defined by the kernel ABI.
397    *
398    * These protocol IDs are used for either kernel implemented
399    * objects, or used for kernel-synthesized requests to user
400    * objects.
401    */
402   enum Protocol
403   {
404     Label_none          = 0, ///< No protocol, the default
405     /**
406      * Value to allow the current system call for an alien thread.
407      *
408      * This value is used in the reply to an alien pre-syscall exception IPC.
409      */
410     Label_allow_syscall = 1,
411
412     Label_irq = -1L,           ///< IRQ object protocol.
413     Label_page_fault = -2L,    ///< Page fault messages use this protocol.
414     Label_preemption = -3L,    ///< Preemption IPC protocol. \note unused.
415     Label_sys_exception = -4L, ///< Sys exception protocol. \note unused.
416     Label_exception  = -5L,    ///< Exception IPC protocol.
417     Label_sigma0 = -6L,        ///< Protocol for sigma0 objects.
418     Label_io_page_fault = -8L, ///< Protocol for I/O-port page faults.
419     Label_kobject = -10L,      ///< Control protocol iD for IPC gates (server
420                                ///  side).
421     Label_task = -11L,         ///< Protocol ID for task and VM objects.
422     Label_thread = -12L,       ///< Protocol ID for thread objects.
423     Label_log = -13L,          ///< Protocol ID for log / vcon objects.
424     Label_scheduler = -14L,    ///< Protocol ID for scheduler objects.
425     Label_factory = -15L,      ///< Protocol ID for factory objects.
426     Label_vm = -16L,           ///< Protocol ID for VM objects (used for create
427                                ///  operations on a factory).
428     Label_semaphore = -20L,    ///< Protocol ID for semaphore objects.
429   };
430 private:
431   Mword _tag;
432 };
433
434 /**
435  * L4 timeouts data type.
436  */
437 class L4_timeout
438 {
439 public:
440   /// Typical timeout constants.
441   enum {
442     Never = 0, ///< Never timeout.
443     Zero  = 0x400, ///< Zero timeout.
444   };
445
446   /**
447    * Create the specified timeout.
448    * @param man mantissa of the send timeout.
449    * @param exp exponent of the send timeout
450    *        (exp=0: infinite timeout,
451    *        exp>0: t=2^(exp)*man,
452    *        man=0 & exp!=0: t=0).
453    */
454   L4_timeout(Mword man, Mword exp);
455   L4_timeout(Mword man, Mword exp, bool clock);
456
457   /**
458    * Create a timeout from it's binary representation.
459    * @param t the binary timeout value.
460    */
461   L4_timeout(unsigned short t = 0);
462
463   /**
464    * Get the binary representation of the timeout.
465    * @return The timeout as binary representation.
466    */
467   unsigned short raw() const;
468
469   /**
470    * Get the receive exponent.
471    * @return The exponent of the receive timeout.
472    * @see rcv_man()
473    */
474   Mword exp() const;
475
476   /**
477    * Set the exponent of the receive timeout.
478    * @param er the exponent for the receive timeout (see L4_timeout()).
479    * @see rcv_man()
480    */
481   void exp(Mword er);
482
483   /**
484    * Get the receive timout's mantissa.
485    * @return The mantissa of the receive timeout (see L4_timeout()).
486    * @see rcv_exp()
487    */
488   Mword man() const;
489
490   /**
491    * Set the mantissa of the receive timeout.
492    * @param mr the mantissa of the recieve timeout (see L4_timeout()).
493    * @see rcv_exp()
494    */
495   void man(Mword mr);
496
497   /**
498    * Get the relative receive timeout in microseconds.
499    * @param clock Current value of kernel clock
500    * @return The receive timeout in micro seconds.
501    */
502   Unsigned64 microsecs_rel(Unsigned64 clock) const;
503
504   /**
505    * Get the absolute receive timeout in microseconds.
506    * @param clock Current value of kernel clock
507    * @return The receive timeout in micro seconds.
508    */
509   Unsigned64 microsecs_abs(Utcb *u) const;
510
511 private:
512   enum
513     {
514       Clock_mask   = 0x0400,
515       Abs_mask     = 0x8000,
516
517       Exp_mask     = 0x7c00,
518       Exp_shift    = 10,
519
520       Man_mask     = 0x3ff,
521       Man_shift    = 0,
522     };
523
524   unsigned short _t;
525 } __attribute__((packed));
526
527 struct L4_timeout_pair
528 {
529   L4_timeout rcv;
530   L4_timeout snd;
531
532   L4_timeout_pair(L4_timeout const &rcv, L4_timeout const &snd)
533     : rcv(rcv), snd(snd) {}
534
535   L4_timeout_pair(unsigned long v) : rcv(v), snd(v >> 16) {}
536
537   Mword raw() const { return (Mword)rcv.raw() | (Mword)snd.raw() << 16; }
538 };
539
540 /**
541  * This class contains constants for the message size for exception IPC.
542  *
543  * This information is architecture dependent, see #Msg_size.
544  */
545 class L4_exception_ipc
546 {};
547
548 class L4_semaphore
549 {
550 public:
551   Smword counter;
552   Mword flags;
553 };
554
555 /**
556  * Constants for error codes returned by kernel objects.
557  */
558 class L4_err
559 {
560 public:
561   enum Err
562   {
563     EPerm         =  1, ///< Permission denied.
564     ENoent        =  2, ///< Some object was not found.
565     ENomem        = 12, ///< Out of memory.
566     EBusy         = 16, ///< The object is busy, try again.
567     EExists       = 17, ///< Some object does already exist.
568     ENodev        = 19, ///< Objects of the specified type cannot be created.
569     EInval        = 22, ///< Invalid parameters passed.
570     ERange        = 34, ///< Parameter out of range
571     ENosys        = 38, ///< No such operation.
572     EBadproto     = 39, ///< Protocol not supported by object.
573
574     EAddrnotavail = 99, ///< The given address is not available.
575   };
576 };
577
578
579 class L4_cpu_set_descr
580 {
581 private:
582   Mword _w;
583
584 public:
585   Mword offset() const { return (_w & 0x00ffffff) & (~0 << granularity()); }
586   Mword granularity() const { return (_w >> 24) & (MWORD_BITS-1) ; }
587 };
588
589 class L4_cpu_set : public L4_cpu_set_descr
590 {
591 private:
592   Mword _map;
593
594 public:
595   bool contains(unsigned cpu) const
596   {
597     if (offset() > cpu)
598       return false;
599
600     cpu -= offset();
601     cpu >>= granularity();
602     if (cpu >= MWORD_BITS)
603       return false;
604
605     return _map & (1UL << cpu);
606   }
607
608   template<typename MAP>
609   Mword first(MAP const &bm, unsigned max) const
610   {
611     unsigned cpu = offset();
612
613     for (;;)
614       {
615         unsigned b = (cpu - offset()) >> granularity();
616         if (cpu >= max || b >= MWORD_BITS)
617           return max;
618
619         if (!(_map & (1UL << b)))
620           {
621             cpu += 1UL << granularity();
622             continue;
623           }
624
625         if (bm.get(cpu))
626           return cpu;
627
628         ++cpu;
629       }
630   }
631 };
632
633 struct L4_sched_param
634 {
635   L4_cpu_set cpus;
636   Smword sched_class; // legacy prio when positive
637   Mword length;       // sizeof (...)
638 };
639
640 struct L4_sched_param_legacy
641 {
642   L4_cpu_set cpus;
643   Smword prio;        // must be positive, overlays with sched_class
644   Mword quantum;
645 };
646
647
648 //----------------------------------------------------------------------------
649 INTERFACE [ia32 || ux]:
650
651 EXTENSION class L4_exception_ipc
652 {
653 public:
654   enum { Msg_size = 16 };
655 };
656
657 //----------------------------------------------------------------------------
658 INTERFACE [arm]:
659
660 EXTENSION class L4_exception_ipc
661 {
662 public:
663   enum { Msg_size = 20 };
664 };
665
666 //----------------------------------------------------------------------------
667 INTERFACE [amd64]:
668
669 EXTENSION class L4_exception_ipc
670 {
671 public:
672   enum { Msg_size = 23 };
673 };
674
675 //----------------------------------------------------------------------------
676 INTERFACE [ppc32]:
677
678 EXTENSION class L4_exception_ipc
679 {
680 public:
681   enum { Msg_size = 39 };
682 };
683
684 INTERFACE [sparc]:
685 EXTENSION class L4_exception_ipc
686 {
687 public:
688   enum { Msg_size = 12 }; // XXX whatever?
689 };
690
691 //----------------------------------------------------------------------------
692 INTERFACE:
693
694 /**
695  * User-level Thread Control Block (UTCB).
696  *
697  * The UTCB is a virtual extension of the registers of a thread. A UTCB
698  * comprises three sets of registers: the message registers (MRs), the buffer
699  * registers (BRs and BDR), and the control registers (TCRs).
700  *
701  * The message registers (MRs) contain the contents of the messages that are
702  * sent to objects or received from objects.  The message contents consist of
703  * untyped data and typed message items (see L4_msg_tag).  The untyped must be
704  * stored in the first \a n message registers (\a n = L4_msg_tag::words()) and
705  * are transferred / copied uninterpreted to the receiving object (MRs of
706  * receiver thread or kernel object).  The typed items follow starting at MR[\a
707  * n+1].  Each typed item is stored in two MRs and is interpreted by the kernel
708  * (see L4_msg_item, L4_fpage). The number of items is denoted by
709  * L4_msg_tag::items().  On the receiver side the typed items are translated
710  * into a format that is useful for the receiver and stored at into the same
711  * MRs in the receivers UTCB.
712  *
713  * The buffer registers (BRs and BDR) contain information that describe receive
714  * buffers for incoming typed items.  The contents of these registers are not
715  * altered by the kernel. The buffer descriptor register (BDR, Utcb::buf_desc)
716  * contains information about the items in the buffer registers (BRs) and
717  * flags to enable FPU state transfer.  The BRs contain a set of receive
718  * message items (L4_msg_item) that describe receive buffers, such as, virtual
719  * memory regions for incoming memory mappings or buffers for capabilities.
720  * The BRs are also used to store absolute 64bit timeout values for operations,
721  * The value of the timeout pair encodes the number of the BR if an absolute
722  * timeout is used.
723  *
724  * The thread control registers (TCRs) comprise an error code for errors during
725  * message passing and a set of user-level registers. The user-level registers
726  * are not used by the kernel and provide and anchor for thread-local storage.
727  */
728 class Utcb
729 {
730   /* must be 2^n bytes */
731 public:
732
733   /**
734    * Type for time values in the UTCB (size is fix 64bit).
735    *
736    * On 32bit architectures this type uses two MRs on 64bit one Mr is used.
737    * This type is used for conversion of time values stored in MRs or BRs.
738    */
739   union Time_val
740   {
741     enum { Words = sizeof(Cpu_time)/sizeof(Mword) /**< Number of MRs used. */ };
742     Mword b[Words]; ///< The array of MRs to use.
743     Cpu_time t;     ///< The time value itself.
744   };
745
746   enum
747   {
748     Max_words = 63,  ///< Number of MRs.
749     Max_buffers = 58 ///< Number of BRs.
750   };
751
752   /// The message registers (MRs).
753   Mword           values[Max_words];
754   Mword           utcb_addr;
755
756   /// The buffer descriptor register (BDR).
757   L4_buf_desc     buf_desc;
758   /// The buffer registers (BRs).
759   Mword           buffers[Max_buffers];
760
761   /// The error code for IPC (TCR).
762   L4_error        error;
763   /// \deprecated transfer timeout is not used currently (TCR).
764   L4_timeout_pair xfer;
765   /// The user-level registers for TLS (TCR).
766   Mword           user[3];
767 };
768
769 //----------------------------------------------------------------------------
770 IMPLEMENTATION:
771
772 #include <minmax.h>
773
774 /**
775  * Receiver is ready to receive FPU contents?
776  * \return true if the receiver is ready to receive the state of the FPU as
777  *         part of a message.
778  * \see L4_buf_desc::Inherit_fpu, L4_buf_desc.
779  */
780 PUBLIC inline
781 bool Utcb::inherit_fpu() const
782 { return buf_desc.flags() & L4_buf_desc::Inherit_fpu; }
783
784
785 /**
786  * Create a message tag from its parts.
787  * \param words the number of untyped message words to transfer.
788  * \param items the number of typed message items, following the untyped words
789  *        in the message registers. See L4_msg_item.
790  * \param flags the flags, see L4_msg_tag::Flags and L4_msg_tag::Output_flags.
791  * \param proto the protocol ID to use.
792  */
793 PUBLIC inline
794 L4_msg_tag::L4_msg_tag(unsigned words, unsigned items, unsigned long flags,
795     unsigned long proto)
796   : _tag((words & 0x3f) | ((items & 0x3f) << 6) | flags | (proto << 16))
797 {}
798
799 /**
800  * Create an uninitialized message tag.
801  * \note the value of the tag is unpredictable.
802  */
803 PUBLIC inline
804 L4_msg_tag::L4_msg_tag()
805 {}
806
807 /**
808  * Create a message tag from another message tag, replacing
809  * the L4_msg_tag::Output_flags.
810  * \param o the message tag to copy.
811  * \param flags the output flags to set in the new tag.
812  * \pre (flags & ~Rcv_flags) == 0
813  */
814 PUBLIC inline
815 L4_msg_tag::L4_msg_tag(L4_msg_tag const &o, Mword flags)
816   : _tag((o.raw() & ~Mword(Rcv_flags)) | flags)
817 {}
818
819 /**
820  * Create msg tag from the binary representation.
821  * \param raw the raw binary representation, as passed from user level.
822  */
823 PUBLIC explicit inline
824 L4_msg_tag::L4_msg_tag(Mword raw)
825   : _tag(raw)
826 {}
827
828 /**
829  * Get the protocol ID.
830  * \return the protocol ID.
831  */
832 PUBLIC inline
833 long
834 L4_msg_tag::proto() const
835 { return long(_tag) >> 16; }
836
837 /**
838  * Get the binary representation.
839  * \return the binary value of the tag.
840  */
841 PUBLIC inline
842 unsigned long
843 L4_msg_tag::raw() const
844 { return _tag; }
845
846 /**
847  * Get the number of untyped words to deliver.
848  * \return number message registers that shall be transferred
849  *         uninterpreted to the receiving object.
850  */
851 PUBLIC inline
852 unsigned L4_msg_tag::words() const
853 { return _tag & 63; }
854
855 /**
856  * Get the number of typed message items in the message.
857  * \return the number of typed items, directly following the
858  *         untyped words in the message registers.
859  * \see L4_msg_item.
860  */
861 PUBLIC inline
862 unsigned L4_msg_tag::items() const
863 { return (_tag >> 6) & 0x3f; }
864
865 /**
866  * Get the flags of the tag.
867  * \return the flags of the message tag, note reserved bits might be
868  *         set in the result.
869  */
870 PUBLIC inline
871 Mword L4_msg_tag::flags() const
872 { return _tag; }
873
874 /**
875  * Transfer the FPU?
876  * \return true if the sender wishes to transfer FPU contents.
877  * \see #Transfer_fpu.
878  */
879 PUBLIC inline
880 bool L4_msg_tag::transfer_fpu() const
881 { return _tag & Transfer_fpu; }
882
883 /**
884  * Do time-slice donation?
885  * \return true if the sender is willing to donate its remaining time-
886  *         slice to the receiver.
887  * \see #Schedule.
888  */
889 PUBLIC inline
890 bool L4_msg_tag::do_switch() const
891 { return !(_tag & Schedule); }
892
893 /**
894  * Set the error flag to \a e.
895  * \param e the value of the error flag to be set.
896  */
897 PUBLIC inline
898 void L4_msg_tag::set_error(bool e = true)
899 { if (e) _tag |= Error; else _tag &= ~Mword(Error); }
900
901 /**
902  * Is there an error flagged?
903  * \return true if the error flag of the message tag is set.
904  */
905 PUBLIC inline
906 bool L4_msg_tag::has_error() const
907 { return _tag & Error; }
908 //
909 // L4_timeout implementation
910 //
911
912 IMPLEMENT inline L4_timeout::L4_timeout(unsigned short t)
913   : _t(t)
914 {}
915
916 IMPLEMENT inline unsigned short L4_timeout::raw() const
917 { return _t; }
918
919 PUBLIC inline
920 Mword L4_timeout::abs_exp() const
921 { return (_t >> 11) & 0xf; }
922
923 PUBLIC inline
924 bool L4_timeout::abs_clock() const
925 { return _t & Clock_mask; }
926
927 IMPLEMENT inline
928 Unsigned64
929 L4_timeout::microsecs_rel(Unsigned64 clock) const
930 {
931   if (man() == 0)
932     return 0;
933   else
934    return clock + ((Unsigned64)man() << exp());
935 }
936
937 IMPLEMENT inline NEEDS[<minmax.h>]
938 Unsigned64
939 L4_timeout::microsecs_abs(Utcb *u) const
940 {
941   int idx = min<int>(_t & 0x3f, Utcb::Max_buffers);
942   Utcb::Time_val const *top
943     = reinterpret_cast<Utcb::Time_val const *>(&u->buffers[idx]);
944   return top->t;
945 }
946
947 PUBLIC inline
948 bool
949 L4_timeout::is_absolute() const
950 { return _t & Abs_mask; }
951
952 PUBLIC inline
953 Unsigned64
954 L4_timeout::microsecs(Unsigned64 clock, Utcb *u) const
955
956   if (is_absolute())
957     return microsecs_abs(u);
958   else
959     return microsecs_rel(clock);
960 }
961
962 PUBLIC inline
963 bool L4_timeout::is_never() const
964 { return !_t; }
965
966 PUBLIC inline
967 bool L4_timeout::is_zero() const
968 { return _t == Zero; }
969
970 PUBLIC inline
971 unsigned short L4_timeout::is_finite() const
972 { return _t; }
973
974
975 //
976 // L4_timeout implementation
977 //
978
979 IMPLEMENT inline
980 L4_timeout::L4_timeout(Mword man, Mword exp)
981 : _t (((man & Man_mask) | ((exp << Exp_shift) & Exp_mask)))
982 {}
983
984 IMPLEMENT inline
985 L4_timeout::L4_timeout(Mword man, Mword exp, bool clock)
986 : _t (((man & Man_mask) | ((exp << (Exp_shift+1)) & Exp_mask)
987       | (clock ? Clock_mask : 0) | Abs_mask))
988 {}
989
990 IMPLEMENT inline Mword L4_timeout::exp() const
991 { return (_t & Exp_mask) >> Exp_shift; }
992
993 IMPLEMENT inline void L4_timeout::exp(Mword w)
994 { _t = (_t & ~Exp_mask) | ((w << Exp_shift) & Exp_mask); }
995
996 IMPLEMENT inline Mword L4_timeout::man() const
997 { return (_t & Man_mask) >> Man_shift; }
998
999 IMPLEMENT inline void L4_timeout::man (Mword w)
1000 { _t = (_t & ~Man_mask) | ((w << Man_shift) & Man_mask); }
1001
1002