]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/abi/l4_fpage.cpp
4c774a9e946d9756cb2704f6b2c9acaec3562992
[l4.git] / kernel / fiasco / src / abi / l4_fpage.cpp
1 INTERFACE:
2
3 #include "types.h"
4
5 #include <bitfield>
6
7 /**
8  * A L4 flex page.
9  *
10  * A flex page represents a naturally aligned area of mappable space,
11  * such as memory, I/O-ports, and capabilities (kernel objects).
12  * There is also a representation for describing a flex page that represents
13  * the whole of all these address spaces. The size of a flex page is given
14  * as a power of two.
15  *
16  *
17  * The internal representation is a single machine word with the following
18  * layout:
19  *   \verbatim
20  *   +- bitsize-12 +- 11-6 -+ 5-4 -+-- 3-0 -+
21  *   | page number | order  | type | rights |
22  *   +-------------+--------+------+--------+
23  *   \endverbatim
24  *
25  *   - The rights bits (0-3) denote the access rights to an object, see
26  *     L4_fpage::Rights.
27  *   - The \a type of a flex page is denotes the address space that is
28  *     referenced by that flex page (see L4_fpage::Type).
29  *   - The order is the exponent for the size calculation (size = 2^order).
30  *   - The page number denotes the page address within the address space
31  *     denoted by \a type. For example when \a type is #Memory, the \a page
32  *     \a number must contain the most significant bits of a virtual address
33  *     that must be aligned to \a order bits.  In the case that \a type
34  *     equals either #Io or #Obj, the \a page \a number contains all bits of
35  *     the I/O-port number or the capability index, respectively (note, the
36  *     values must also be aligned according to the value of \a order).
37  *
38  */
39 class L4_fpage
40 {
41 public:
42   /**
43    * Data type to represent the binary representation of a flex page.
44    */
45   typedef Mword Raw;
46
47   /**
48    * Address space type of a flex page.
49    */
50   enum Type
51   {
52     Special = 0, ///< Special flex pages, either invalid or all spaces.
53     Memory,      ///< Memory flex page
54     Io,          ///< I/O-port flex page
55     Obj          ///< Object flex page (capabilities)
56   };
57
58   enum { Addr_shift = 12 };
59
60 private:
61   /**
62    * Create a flex page with the given parameters.
63    */
64   L4_fpage(Type type, Mword address, unsigned char order,
65            unsigned char rights)
66   : _raw(  address | rights_bfm_t::val_dirty(rights)
67          | order_bfm_t::val_dirty(order) | type_bfm_t::val_dirty(type))
68   {}
69
70 public:
71   enum
72   {
73     Whole_space = 63 ///< Value to use as \a order for a whole address space.
74   };
75
76   /**
77    * Create an I/O flex page.
78    *
79    * IO flex pages do not support access rights other than RW or nothing.
80    * \param port base I/O-port number (0..65535), must be aligned to
81    *             2^\a order. The value is shifted by #Addr_shift bits to the
82    *             left.
83    * \param order the order of the I/O flex page, size is 2^\a order ports.
84    */
85   static L4_fpage io(Mword port, unsigned char order)
86   { return L4_fpage(Io, adr_bfm_t::val_dirty(port), order, 0); }
87
88   /**
89    * Create an object flex page.
90    *
91    * \param idx capability index, note capability indexes are multiples of
92    *            0x1000. (hence \a idx is not shifted)
93    * \param order The size of the flex page is 2^\a order. The value in \a idx
94    *              must be aligned to 2^(\a order + #Addr_shift.
95    */
96   static L4_fpage obj(Mword idx, unsigned char order, unsigned char rights = 0)
97   { return L4_fpage(Obj, idx & adr_bfm_t::Mask, order, rights); }
98
99   /**
100    * Create a memory flex page.
101    *
102    * \param addr The virtual address. Only the most significant bits are
103    *             considered, bits from 0 to \a order-1 are dropped.
104    * \param order The size of the flex page is 2^\a order in bytes.
105    */
106   static L4_fpage mem(Mword addr, unsigned char order, unsigned char rights = 0)
107   { return L4_fpage(Memory, addr & adr_bfm_t::Mask, order, rights); }
108
109   /**
110    * Create a nil (invalid) flex page.
111    */
112   static L4_fpage nil()
113   { return L4_fpage(0); }
114
115   /**
116    * Create a special receive flex page representing
117    * all available address spaces at once. This is used
118    * for page-fault and exception IPC.
119    */
120   static L4_fpage all_spaces(unsigned char rights = 0)
121   { return L4_fpage(Special, 0, Whole_space, rights); }
122
123   /**
124    * Create a flex page from the raw value.
125    */
126   explicit L4_fpage(Raw raw) : _raw(raw) {}
127
128   /**
129    * The robust type for carrying virtual memory addresses.
130    */
131   typedef Virt_addr Mem_addr;
132
133   /**
134    * Get the virtual address of a memory flex page.
135    *
136    * \pre type() must return #Memory to return a valid value.
137    * \return The virtual memory base address of the flex page.
138    */
139   Virt_addr mem_address() const
140   { return Virt_addr(adr_bfm_t::get_unshifted(_raw)); }
141
142   /**
143    * Get the capability address of an object flex page.
144    *
145    * \pre type() must return #Obj to return a valid value.
146    * \return The capability value (index) of this flex page.
147    *         This value is not shifted, so it is a multiple of 0x1000.
148    *         See obj_index() for reference.
149    */
150   Mword obj_address() const { return adr_bfm_t::get_unshifted(_raw); }
151
152   /**
153    * Get the I/O-port number of an I/O flex page.
154    * \pre type() must return #Io to return a valid value.
155    * \return The I/O-port index of this flex page.
156    */
157   Mword io_address() const { return adr(); }
158
159   /**
160    * Get the capability index of an object flex page.
161    *
162    * \pre type() must return #Obj to return a valid value.
163    * \return The index into the capability table provided by this flex page.
164    *         This value is shifted #Addr_shift to be a real index
165    *         (opposed to obj_address()).
166    */
167   Mword obj_index() const { return adr(); }
168
169   /**
170    * Test for memory flex page (if type() is #Memory).
171    * \return true if type() is #Memory.
172    */
173   bool is_mempage() const { return type() == Memory; }
174
175   /**
176    * Test for I/O flex page (if type() is #Io).
177    * \return true if type() is #Io.
178    */
179   bool is_iopage() const { return type() == Io; }
180
181   /**
182    * Test for object flex page (if type() is #Obj).
183    * \return true if type() is #Obj.
184    */
185   bool is_objpage() const { return type() == Obj; }
186
187
188   /**
189    * Is the flex page the whole address space?
190    * @return not zero, if the flex page covers the
191    *   whole address space.
192    */
193   Mword is_all_spaces() const
194   { return (_raw & (type_bfm_t::Mask | order_bfm_t::Mask)) == order_bfm_t::val(Whole_space); }
195
196   /**
197    * Is the flex page valid?
198    * \return not zero if the flex page
199    *    contains a value other than 0.
200    */
201   Mword is_valid() const { return _raw; }
202
203   /**
204    * Get the binary representation of the flex page.
205    * \return this flex page in binary representation.
206    */
207   Raw raw() const { return _raw; }
208
209 private:
210   Raw _raw;
211
212 public:
213
214   /** \name Rights of the flex page */
215   CXX_BITFIELD_MEMBER( 0,  3, rights, _raw);
216   /** \name Type of the flex page */
217   CXX_BITFIELD_MEMBER( 4,  5, type, _raw);
218   /** \name Size (as power of 2) of the flex page */
219   CXX_BITFIELD_MEMBER( 6, 11, order, _raw);
220 private:
221   /** \name Address encoded in the flex page */
222   CXX_BITFIELD_MEMBER(12, MWORD_BITS-1, adr, _raw);
223
224 public:
225   /**
226    * Rights bits for flex pages.
227    *
228    * The particular semantics of the rights bits in a flex page differ depending on the
229    * type of the flex page. For memory there are #R, #W, and #X rights. For
230    * I/O-ports there must be #R and #W, to get access. For object (capabilities)
231    * there are #CD, #CR, #CS, and #CW rights on the object and additional
232    * rights in the map control value of the map operation (see L4_fpage::Obj_map_ctl).
233    */
234   enum Rights
235   {
236     R   = 4, ///< Memory flex page is readable
237     W   = 2, ///< Memory flex page is writable
238     X   = 1, ///< Memory flex page is executable (often equal to #R)
239
240     RX  = R | X,     ///< Memory flex page is readable and executable
241     RWX = R | W | X, ///< Memory flex page is readable, writeable, and executable
242     RW  = R | W,     ///< Memory flex page is readable and writable
243     WX  = W | X,     ///< Memory flex page is writable and executable
244
245
246     CD    = 0x8, ///< Object flex page: delete rights
247     CR    = 0x4, ///< Object flex page: read rights (w/o this the mapping is not present)
248     CS    = 0x2, ///< Object flex page: strong semantics (object specific, i.e. not having
249                  ///  this right on an IPC gate demotes all capabilities transferred via this
250                  ///  IPC gate to also suffer this right.
251     CW    = 0x1, ///< Object flex page: write rights (purely object specific)
252
253     CRW   = CR | CW,       ///< Object flex page: combine #CR and #CW
254     CRS   = CR | CS,       ///< Object flex page: combine #CR and #CS
255     CRWS  = CRW | CS,      ///< Object flex page: combine #CR, #CW, and #CS
256     CWS   = CW | CS,       ///< Object flex page: combine #CS and #CW
257     CWSD  = CW | CS | CD,  ///< Object flex page: combine #CS, #CW, and #CD
258     CRWSD = CRWS | CD,     ///< Object flex page: combine #CR, #CW, #CS, and #CD
259
260     FULL  = 0xf, ///< All rights shall be transferred, independent of the type
261   };
262
263   /**
264    * Remove the given rights from this flex page.
265    * \param r the rights to remove. The semantics depend on the
266    *          type (type()) of the flex page.
267    */
268   void mask_rights(Rights r) { _raw &= (Mword(r) | ~rights_bfm_t::Mask); }
269 };
270