8 * A flex page represents a naturally aligned area of mappable space,
9 * such as memory, I/O-ports, and capabilities (kernel objects).
10 * There is also a representation for describing a flex page that represents
11 * the whole of all these address spaces. The size of a flex page is given
15 * The internal representation is a single machine word with the following
18 * +- bitsize-12 +- 11-6 -+ 5-4 -+-- 3-0 -+
19 * | page number | order | type | rights |
20 * +-------------+--------+------+--------+
23 * - The rights bits (0-3) denote the access rights to an object, see
25 * - The \a type of a flex page is denotes the address space that is
26 * referenced by that flex page (see L4_fpage::Type).
27 * - The order is the exponent for the size calculation (size = 2^order).
28 * - The page number denotes the page address within the address space
29 * denoted by \a type. For example when \a type is #Memory, the \a page
30 * \a number must contain the most significant bits of a virtual address
31 * that must be aligned to \a order bits. In the case that \a type
32 * equals either #Io or #Obj, the \a page \a number contains all bits of
33 * the I/O-port number or the capability index, respectively (note, the
34 * values must also be aligned according to the value of \a order).
41 * Data type to represent the binary representation of a flex page.
46 * Address space type of a flex page.
50 Special = 0, ///< Special flex pages, either invalid or all spaces.
51 Memory, ///< Memory flex page
52 Io, ///< I/O-port flex page
53 Obj ///< Object flex page (capabilities)
56 enum { Addr_shift = 12 };
60 * Create a flex page with the given parameters.
62 L4_fpage(Type type, Mword address, unsigned char order,
64 : _raw(address | Raw(rights) | (Raw(order) << 6) | (Raw(type) << 4))
70 Whole_space = 63 ///< Value to use as \a order for a whole address space.
74 * Create an I/O flex page.
76 * IO flex pages do not support access rights other than RW or nothing.
77 * \param port base I/O-port number (0..65535), must be aligned to
78 * 2^\a order. The value is shifted by #Addr_shift bits to the
80 * \param order the order of the I/O flex page, size is 2^\a order ports.
82 static L4_fpage io(Mword port, unsigned char order)
83 { return L4_fpage(Io, port << Addr_shift, order, 0); }
86 * Create an object flex page.
88 * \param idx capability index, note capability indexes are multiples of
89 * 0x1000. (hence \a idx is not shifted)
90 * \param order The size of the flex page is 2^\a order. The value in \a idx
91 * must be aligned to 2^(\a order + #Addr_shift.
93 static L4_fpage obj(Mword idx, unsigned char order, unsigned char rights = 0)
94 { return L4_fpage(Obj, idx & (~0UL << Addr_shift), order, rights); }
97 * Create a memory flex page.
99 * \param addr The virtual address. Only the most significant bits are
100 * considered, bits from 0 to \a order-1 are dropped.
101 * \param order The size of the flex page is 2^\a order in bytes.
103 static L4_fpage mem(Mword addr, unsigned char order, unsigned char rights = 0)
104 { return L4_fpage(Memory, addr & (~0UL << Addr_shift), order, rights); }
107 * Create a nil (invalid) flex page.
109 static L4_fpage nil()
110 { return L4_fpage(0); }
113 * Create a special receive flex page representing
114 * all available address spaces at once. This is used
115 * for page-fault and exception IPC.
117 static L4_fpage all_spaces(unsigned char rights = 0)
118 { return L4_fpage(Special, 0, Whole_space, rights); }
121 * Create a flex page from the raw value.
123 explicit L4_fpage(Raw raw) : _raw(raw) {}
126 * Get the type, see #L4_fpage::Type.
127 * \return the type of the flex page.
129 Type type() const { return Type((_raw >> 4) & 3); }
132 * Get the order of a flex page.
133 * \return the order of the flex page (size is 2^\a order).
135 unsigned char order() const { return (_raw >> 6) & 0x3f; }
138 * The robust type for carrying virtual memory addresses.
140 typedef Virt_addr Mem_addr;
143 * Get the virtual address of a memory flex page.
145 * \pre type() must return #Memory to return a valid value.
146 * \return The virtual memory base address of the flex page.
148 Virt_addr mem_address() const
149 { return Virt_addr(_raw & (~0UL << Addr_shift)); }
152 * Get the capability address of an object flex page.
154 * \pre type() must return #Obj to return a valid value.
155 * \return The capability value (index) of this flex page.
156 * This value is not shifted, so it is a multiple of 0x1000.
157 * See obj_index() for reference.
159 Mword obj_address() const { return _raw & (~0UL << Addr_shift); }
162 * Get the I/O-port number of an I/O flex page.
163 * \pre type() must return #Io to return a valid value.
164 * \return The I/O-port index of this flex page.
166 Mword io_address() const { return _raw >> Addr_shift; }
169 * Get the capability index of an object flex page.
171 * \pre type() must return #Obj to return a valid value.
172 * \return The index into the capability table provided by this flex page.
173 * This value is shifted #Addr_shift to be a real index
174 * (opposed to obj_address()).
176 Mword obj_index() const { return _raw >> Addr_shift; }
179 * Test for memory flex page (if type() is #Memory).
180 * \return true if type() is #Memory.
182 bool is_mempage() const { return type() == Memory; }
185 * Test for I/O flex page (if type() is #Io).
186 * \return true if type() is #Io.
188 bool is_iopage() const { return type() == Io; }
191 * Test for object flex page (if type() is #Obj).
192 * \return true if type() is #Obj.
194 bool is_objpage() const { return type() == Obj; }
198 * Is the flex page the whole address space?
199 * @return not zero, if the flex page covers the
200 * whole address space.
202 Mword is_all_spaces() const { return (_raw & 0xff8) == (Whole_space << 6); }
205 * Is the flex page valid?
206 * \return not zero if the flex page
207 * contains a value other than 0.
209 Mword is_valid() const { return _raw; }
212 * Get the binary representation of the flex page.
213 * \return this flex page in binary representation.
215 Raw raw() const { return _raw; }
223 * Rights bits for flex pages.
225 * The particular semantics of the rights bits in a flex page differ depending on the
226 * type of the flex page. For memory there are #R, #W, and #X rights. For
227 * I/O-ports there must be #R and #W, to get access. For object (capabilities)
228 * there are #CD, #CR, #CS, and #CW rights on the object and additional
229 * rights in the map control value of the map operation (see L4_fpage::Obj_map_ctl).
233 R = 4, ///< Memory flex page is readable
234 W = 2, ///< Memory flex page is writable
235 X = 1, ///< Memory flex page is executable (often equal to #R)
237 RX = R | X, ///< Memory flex page is readable and executable
238 RWX = R | W | X, ///< Memory flex page is readable, writeable, and executable
239 RW = R | W, ///< Memory flex page is readable and writable
240 WX = W | X, ///< Memory flex page is writable and executable
243 CD = 0x8, ///< Object flex page: delete rights
244 CR = 0x4, ///< Object flex page: read rights (w/o this the mapping is not present)
245 CS = 0x2, ///< Object flex page: strong semantics (object specific, i.e. not having
246 /// this right on an IPC gate demotes all capabilities transferred via this
247 /// IPC gate to also suffer this right.
248 CW = 0x1, ///< Object flex page: write rights (purely object specific)
250 CRW = CR | CW, ///< Object flex page: combine #CR and #CW
251 CRS = CR | CS, ///< Object flex page: combine #CR and #CS
252 CRWS = CRW | CS, ///< Object flex page: combine #CR, #CW, and #CS
253 CWS = CW | CS, ///< Object flex page: combine #CS and #CW
254 CWSD = CW | CS | CD, ///< Object flex page: combine #CS, #CW, and #CD
255 CRWSD = CRWS | CD, ///< Object flex page: combine #CR, #CW, #CS, and #CD
257 FULL = 0xf, ///< All rights shall be transferred, independent of the type
261 * Get the rights associated with this flexpage.
262 * \return The rights associated with this flex page. The semantics of this
263 * value also depends on the type (type()) of the flex page.
265 Rights rights() const { return Rights(_raw & FULL); }
268 * Remove the given rights from this flex page.
269 * \param r the rights to remove. The semantics depend on the
270 * type (type()) of the flex page.
272 void mask_rights(Rights r) { _raw &= (Mword(r) | ~0x0fUL); }