]> rtime.felk.cvut.cz Git - l4.git/blobdiff - kernel/fiasco/src/abi/l4_fpage.cpp
update
[l4.git] / kernel / fiasco / src / abi / l4_fpage.cpp
index 97ed692a1be745d91a135efc6d4ea23cdb6c7009..9fdb27772b2e6dc06d76ac999e9af539e87bb9d0 100644 (file)
@@ -5,27 +5,59 @@ INTERFACE:
 /**
  * A L4 flex page.
  *
- * A flex page represents a size aligned
- * region of an address space.
+ * A flex page represents a naturally aligned area of mappable space,
+ * such as memory, I/O-ports, and capabilities (kernel objects).
+ * There is also a representation for describing a flex page that represents
+ * the whole of all these address spaces. The size of a flex page is given
+ * as a power of two.
+ *
+ *
+ * The internal representation is a single machine word with the following
+ * layout:
+ *   \verbatim
+ *   +- bitsize-12 +- 11-6 -+ 5-4 -+-- 3-0 -+
+ *   | page number | order  | type | rights |
+ *   +-------------+--------+------+--------+
+ *   \endverbatim
+ *
+ *   - The rights bits (0-3) denote the access rights to an object, see
+ *     L4_fpage::Rights.
+ *   - The \a type of a flex page is denotes the address space that is
+ *     referenced by that flex page (see L4_fpage::Type).
+ *   - The order is the exponent for the size calculation (size = 2^order).
+ *   - The page number denotes the page address within the address space
+ *     denoted by \a type. For example when \a type is #Memory, the \a page
+ *     \a number must contain the most significant bits of a virtual address
+ *     that must be aligned to \a order bits.  In the case that \a type
+ *     equals either #Io or #Obj, the \a page \a number contains all bits of
+ *     the I/O-port number or the capability index, respectively (note, the
+ *     values must also be aligned according to the value of \a order).
+ *
  */
 class L4_fpage
 {
 public:
+  /**
+   * Data type to represent the binary representation of a flex page.
+   */
   typedef Mword Raw;
 
+  /**
+   * Address space type of a flex page.
+   */
   enum Type
   {
-    Special = 0,
-    Memory,
-    Io,
-    Obj
+    Special = 0, ///< Special flex pages, either invalid or all spaces.
+    Memory,      ///< Memory flex page
+    Io,          ///< I/O-port flex page
+    Obj          ///< Object flex page (capabilities)
   };
 
   enum { Addr_shift = 12 };
 
 private:
   /**
-   * Create a flexpage with the given parameters.
+   * Create a flex page with the given parameters.
    */
   L4_fpage(Type type, Mword address, unsigned char order,
            unsigned char rights)
@@ -33,43 +65,134 @@ private:
   {}
 
 public:
-  enum { Whole_space = 63 };
+  enum
+  {
+    Whole_space = 63 ///< Value to use as \a order for a whole address space.
+  };
 
+  /**
+   * Create an I/O flex page.
+   *
+   * IO flex pages do not support access rights other than RW or nothing.
+   * \param port base I/O-port number (0..65535), must be aligned to
+   *             2^\a order. The value is shifted by #Addr_shift bits to the
+   *             left.
+   * \param order the order of the I/O flex page, size is 2^\a order ports.
+   */
   static L4_fpage io(Mword port, unsigned char order)
   { return L4_fpage(Io, port << Addr_shift, order, 0); }
 
+  /**
+   * Create an object flex page.
+   *
+   * \param idx capability index, note capability indexes are multiples of
+   *            0x1000. (hence \a idx is not shifted)
+   * \param order The size of the flex page is 2^\a order. The value in \a idx
+   *              must be aligned to 2^(\a order + #Addr_shift.
+   */
   static L4_fpage obj(Mword idx, unsigned char order, unsigned char rights = 0)
   { return L4_fpage(Obj, idx & (~0UL << Addr_shift), order, rights); }
 
+  /**
+   * Create a memory flex page.
+   *
+   * \param addr The virtual address. Only the most significant bits are
+   *             considered, bits from 0 to \a order-1 are dropped.
+   * \param order The size of the flex page is 2^\a order in bytes.
+   */
   static L4_fpage mem(Mword addr, unsigned char order, unsigned char rights = 0)
   { return L4_fpage(Memory, addr & (~0UL << Addr_shift), order, rights); }
 
+  /**
+   * Create a nil (invalid) flex page.
+   */
   static L4_fpage nil()
   { return L4_fpage(0); }
 
+  /**
+   * Create a special receive flex page representing
+   * all available address spaces at once. This is used
+   * for page-fault and exception IPC.
+   */
   static L4_fpage all_spaces(unsigned char rights = 0)
   { return L4_fpage(Special, 0, Whole_space, rights); }
 
+  /**
+   * Create a flex page from the raw value.
+   */
   explicit L4_fpage(Raw raw) : _raw(raw) {}
 
-  Type type() const           { return Type((_raw >> 4) & 3); }
+  /**
+   * Get the type, see #L4_fpage::Type.
+   * \return the type of the flex page.
+   */
+  Type type() const { return Type((_raw >> 4) & 3); }
+
+  /**
+   * Get the order of a flex page.
+   * \return the order of the flex page (size is 2^\a order).
+   */
   unsigned char order() const { return (_raw >> 6) & 0x3f; }
 
+  /**
+   * The robust type for carrying virtual memory addresses.
+   */
   typedef Virt_addr Mem_addr;
+
+  /**
+   * Get the virtual address of a memory flex page.
+   *
+   * \pre type() must return #Memory to return a valid value.
+   * \return The virtual memory base address of the flex page.
+   */
   Virt_addr mem_address() const
   { return Virt_addr(_raw & (~0UL << Addr_shift)); }
 
-  Mword obj_address() const   { return _raw & (~0UL << Addr_shift); }
-  Mword io_address() const    { return _raw >> Addr_shift; }
-  Mword obj_index() const     { return _raw >> Addr_shift; }
+  /**
+   * Get the capability address of an object flex page.
+   *
+   * \pre type() must return #Obj to return a valid value.
+   * \return The capability value (index) of this flex page.
+   *         This value is not shifted, so it is a multiple of 0x1000.
+   *         See obj_index() for reference.
+   */
+  Mword obj_address() const { return _raw & (~0UL << Addr_shift); }
 
+  /**
+   * Get the I/O-port number of an I/O flex page.
+   * \pre type() must return #Io to return a valid value.
+   * \return The I/O-port index of this flex page.
+   */
+  Mword io_address() const { return _raw >> Addr_shift; }
+
+  /**
+   * Get the capability index of an object flex page.
+   *
+   * \pre type() must return #Obj to return a valid value.
+   * \return The index into the capability table provided by this flex page.
+   *         This value is shifted #Addr_shift to be a real index
+   *         (opposed to obj_address()).
+   */
+  Mword obj_index() const { return _raw >> Addr_shift; }
+
+  /**
+   * Test for memory flex page (if type() is #Memory).
+   * \return true if type() is #Memory.
+   */
   bool is_mempage() const { return type() == Memory; }
-  bool is_iopage()  const { return type() == Io; }
+
+  /**
+   * Test for I/O flex page (if type() is #Io).
+   * \return true if type() is #Io.
+   */
+  bool is_iopage() const { return type() == Io; }
+
+  /**
+   * Test for object flex page (if type() is #Obj).
+   * \return true if type() is #Obj.
+   */
   bool is_objpage() const { return type() == Obj; }
 
-  Mword write() const { return _raw & 2; }
-  Mword read() const  { return _raw & 4; }
-  Mword exec() const  { return _raw & 1; }
 
   /**
    * Is the flex page the whole address space?
@@ -80,82 +203,72 @@ public:
 
   /**
    * Is the flex page valid?
-   * @return not zero if the flex page
+   * \return not zero if the flex page
    *    contains a value other than 0.
    */
   Mword is_valid() const { return _raw; }
 
   /**
    * Get the binary representation of the flex page.
-   * @return this flex page in binary representation.
+   * \return this flex page in binary representation.
    */
   Raw raw() const { return _raw; }
 
 private:
-
   Raw _raw;
 
-  enum {
-    /* +- bitsize-12 +- 11-6 -+ 5-3 -+ 2-0 +
-     * | page number |  size  | type | rwx |
-     * +-------------+--------+------+-----+ */
-
-    // Extension: bits for returning a flexpage's access status.
-    // (Make sure these flags do not overlap any significant fpage
-    // bits -- but overlapping the Grant and Write bits used in some
-    // APIs is OK.)
-  };
-
 public:
-  enum
-  {
-    Caching_opt = 1,
-    Cached      = 3,
-    Buffered    = 5,
-    Uncached    = 1,
-
-    Control_addr_shift = 12,
-    Control_grant      = 2,
-  };
-
-  enum Obj_map_ctl
-  {
-    C_weak_ref            = 0x10,
-    C_ref                 = 0x00,
-
-    C_obj_right_1         = 0x20,
-    C_obj_right_2         = 0x40,
-    C_obj_right_3         = 0x80,
-
-    C_obj_specific_rights = C_obj_right_1 | C_obj_right_2 | C_obj_right_3,
-    C_ctl_rights          = C_obj_specific_rights | C_weak_ref,
-  };
 
+  /**
+   * Rights bits for flex pages.
+   *
+   * The particular semantics of the rights bits in a flex page differ depending on the
+   * type of the flex page. For memory there are #R, #W, and #X rights. For
+   * I/O-ports there must be #R and #W, to get access. For object (capabilities)
+   * there are #CD, #CR, #CS, and #CW rights on the object and additional
+   * rights in the map control value of the map operation (see L4_fpage::Obj_map_ctl).
+   */
   enum Rights
   {
-    R   = 4,
-    W   = 2,
-    X   = 1,
-    RX  = R | X,
-    RWX = R | W | X,
-    RW  = R | W,
-    WX  = W | X,
-
-    CD    = 0x8,
-    CR    = 0x4,
-    CS    = 0x2,
-    CW    = 0x1,
-    CRW   = CR | CW,
-    CRS   = CR | CS,
-    CRWS  = CRW | CS,
-    CWS   = CW | CS,
-    CWSD  = CW | CS | CD,
-    CRWSD = CRWS | CD,
-
-    FULL  = 0xf,
+    R   = 4, ///< Memory flex page is readable
+    W   = 2, ///< Memory flex page is writable
+    X   = 1, ///< Memory flex page is executable (often equal to #R)
+
+    RX  = R | X,     ///< Memory flex page is readable and executable
+    RWX = R | W | X, ///< Memory flex page is readable, writeable, and executable
+    RW  = R | W,     ///< Memory flex page is readable and writable
+    WX  = W | X,     ///< Memory flex page is writable and executable
+
+
+    CD    = 0x8, ///< Object flex page: delete rights
+    CR    = 0x4, ///< Object flex page: read rights (w/o this the mapping is not present)
+    CS    = 0x2, ///< Object flex page: strong semantics (object specific, i.e. not having
+                 ///  this right on an IPC gate demotes all capabilities transferred via this
+                 ///  IPC gate to also suffer this right.
+    CW    = 0x1, ///< Object flex page: write rights (purely object specific)
+
+    CRW   = CR | CW,       ///< Object flex page: combine #CR and #CW
+    CRS   = CR | CS,       ///< Object flex page: combine #CR and #CS
+    CRWS  = CRW | CS,      ///< Object flex page: combine #CR, #CW, and #CS
+    CWS   = CW | CS,       ///< Object flex page: combine #CS and #CW
+    CWSD  = CW | CS | CD,  ///< Object flex page: combine #CS, #CW, and #CD
+    CRWSD = CRWS | CD,     ///< Object flex page: combine #CR, #CW, #CS, and #CD
+
+    FULL  = 0xf, ///< All rights shall be transferred, independent of the type
   };
 
+  /**
+   * Get the rights associated with this flexpage.
+   * \return The rights associated with this flex page. The semantics of this
+   *         value also depends on the type (type()) of the flex page.
+   */
   Rights rights() const { return Rights(_raw & FULL); }
+
+  /**
+   * Remove the given rights from this flex page.
+   * \param r the rights to remove. The semantics depend on the
+   *          type (type()) of the flex page.
+   */
   void mask_rights(Rights r) { _raw &= (Mword(r) | ~0x0fUL); }
 };