L4Re – L4 Runtime Environment
rm
Go to the documentation of this file.
1 // -*- Mode: C++ -*-
2 // vim:ft=cpp
7 /*
8  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9  * Alexander Warg <warg@os.inf.tu-dresden.de>,
10  * Björn Döbel <doebel@os.inf.tu-dresden.de>,
11  * Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
12  * economic rights: Technische Universität Dresden (Germany)
13  *
14  * This file is part of TUD:OS and distributed under the terms of the
15  * GNU General Public License 2.
16  * Please see the COPYING-GPL-2 file for details.
17  *
18  * As a special exception, you may use this file as part of a free software
19  * library without restriction. Specifically, if other files instantiate
20  * templates or use macros or inline functions from this file, or you compile
21  * this file and link it with other files to produce an executable, this
22  * file does not by itself cause the resulting executable to be covered by
23  * the GNU General Public License. This exception does not however
24  * invalidate any other reasons why the executable file might be covered by
25  * the GNU General Public License.
26  */
27 #pragma once
28 
29 #include <l4/sys/types.h>
30 #include <l4/sys/l4int.h>
31 #include <l4/sys/capability>
32 #include <l4/re/protocols.h>
33 #include <l4/sys/pager>
34 #include <l4/sys/cxx/ipc_iface>
35 #include <l4/sys/cxx/ipc_ret_array>
36 #include <l4/sys/cxx/types>
37 #include <l4/re/consts>
38 #include <l4/re/dataspace>
39 
40 namespace L4Re {
41 
73 class L4_EXPORT Rm :
74  public L4::Kobject_t<Rm, L4::Pager, L4RE_PROTO_RM,
75  L4::Type_info::Demand_t<1> >
76 {
77 public:
78  typedef L4Re::Dataspace::Offset Offset;
79 
82  {
83  Detached_ds = 0,
84  Kept_ds = 1,
85  Split_ds = 2,
86  Detach_result_mask = 3,
87 
88  Detach_again = 4,
89  };
90 
91 
93  {
95  Caching_shift = Dataspace::F::Caching_shift,
96  };
97 
99  struct F
100  {
103  {
105  Search_addr = 0x20000,
107  In_area = 0x40000,
109  Eager_map = 0x80000,
111  Attach_mask = 0xf0000,
112  };
113 
115 
117  {
119  Rights_mask = 0x0f,
120  R = Dataspace::F::R,
121  W = Dataspace::F::W,
122  X = Dataspace::F::X,
123  RW = Dataspace::F::RW,
124  RX = Dataspace::F::RX,
125  RWX = Dataspace::F::RWX,
126 
128  Detach_free = 0x200,
130  Pager = 0x400,
132  Reserved = 0x800,
133 
134 
138  Cache_normal = Dataspace::F::Normal,
140  Cache_buffered = Dataspace::F::Bufferable,
142  Cache_uncached = Dataspace::F::Uncacheable,
143 
145  Ds_map_mask = 0xff,
146 
148  Region_flags_mask = 0xffff,
149  };
150 
152 
153  friend constexpr Dataspace::Flags map_flags(Region_flags rf)
154  {
155  return Dataspace::Flags((l4_uint16_t)rf & Ds_map_mask);
156  }
157 
158  struct Flags : L4::Types::Flags_ops_t<Flags>
159  {
160  l4_uint32_t raw;
161  Flags() = default;
162  explicit constexpr Flags(l4_uint32_t f) : raw(f) {}
163  constexpr Flags(Attach_flags rf) : raw((l4_uint32_t)rf) {}
164  constexpr Flags(Region_flags rf) : raw((l4_uint32_t)rf) {}
165 
166  friend constexpr Dataspace::Flags map_flags(Flags f)
167  {
168  return Dataspace::Flags(f.raw & Ds_map_mask);
169  }
170 
171  constexpr Region_flags region_flags() const
172  {
173  return Region_flags(raw & Region_flags_mask);
174  }
175 
176  constexpr Attach_flags attach_flags() const
177  {
178  return Attach_flags(raw & Attach_mask);
179  }
180 
181  constexpr bool r() const { return raw & L4_FPAGE_RO; }
182  constexpr bool w() const { return raw & L4_FPAGE_W; }
183  constexpr bool x() const { return raw & L4_FPAGE_X; }
184  constexpr unsigned cap_rights() const
185  { return w() ? L4_CAP_FPAGE_RW : L4_CAP_FPAGE_RO; }
186  };
187 
188  friend constexpr Flags operator | (Region_flags l, Attach_flags r)
189  { return Flags(l) | Flags(r); }
190 
191  friend constexpr Flags operator | (Attach_flags l, Region_flags r)
192  { return Flags(l) | Flags(r); }
193  };
194 
195  using Attach_flags = F::Attach_flags;
196  using Region_flags = F::Region_flags;
197  using Flags = F::Flags;
198 
201  {
211  Detach_exact = 1,
221  Detach_overlap = 2,
222 
230  Detach_keep = 4,
231  };
232 
258  long reserve_area(l4_addr_t *start, unsigned long size,
259  Flags flags = Flags(0),
260  unsigned char align = L4_PAGESHIFT) const noexcept
261  { return reserve_area_t::call(c(), start, size, flags, align); }
262 
263  L4_RPC_NF(long, reserve_area, (L4::Ipc::In_out<l4_addr_t *> start,
264  unsigned long size,
265  Flags flags,
266  unsigned char align));
267 
283  template< typename T >
284  long reserve_area(T **start, unsigned long size,
285  Flags flags = Flags(0),
286  unsigned char align = L4_PAGESHIFT) const noexcept
287  { return reserve_area_t::call(c(), (l4_addr_t*)start, size, flags, align); }
288 
301  L4_RPC(long, free_area, (l4_addr_t addr));
302 
303  L4_RPC_NF(long, attach, (L4::Ipc::In_out<l4_addr_t *> start,
304  unsigned long size, Flags flags,
306  Offset offs, unsigned char align,
307  L4::Ipc::Opt<l4_cap_idx_t> client_cap));
308 
309  L4_RPC_NF(long, detach, (l4_addr_t addr, unsigned long size, unsigned flags,
310  l4_addr_t &start, l4_addr_t &rsize,
311  l4_cap_idx_t &mem_cap));
312 
361  long attach(l4_addr_t *start, unsigned long size, Flags flags,
362  L4::Ipc::Cap<Dataspace> mem, Offset offs = 0,
363  unsigned char align = L4_PAGESHIFT) const noexcept;
364 
368  template< typename T >
369  long attach(T **start, unsigned long size, Flags flags,
370  L4::Ipc::Cap<Dataspace> mem, Offset offs = 0,
371  unsigned char align = L4_PAGESHIFT) const noexcept
372  {
373  union X { l4_addr_t a; T* t; };
374  X *x = reinterpret_cast<X*>(start);
375  return attach(&x->a, size, flags, mem, offs, align);
376  }
377 
378 #if __cplusplus >= 201103L
379  template< typename T >
380  class Unique_region
381  {
382  private:
383  T _addr;
384  L4::Cap<Rm> _rm;
385 
386  public:
387  Unique_region(Unique_region const &) = delete;
388  Unique_region &operator = (Unique_region const &) = delete;
389 
390  Unique_region() noexcept
391  : _addr(0), _rm(L4::Cap<Rm>::Invalid) {}
392 
393  explicit Unique_region(T addr) noexcept
394  : _addr(addr), _rm(L4::Cap<Rm>::Invalid) {}
395 
396  Unique_region(T addr, L4::Cap<Rm> const &rm) noexcept
397  : _addr(addr), _rm(rm) {}
398 
399  Unique_region(Unique_region &&o) noexcept : _addr(o.get()), _rm(o._rm)
400  { o.release(); }
401 
402  Unique_region &operator = (Unique_region &&o) noexcept
403  {
404  if (&o != this)
405  {
406  if (_rm.is_valid())
407  _rm->detach(l4_addr_t(_addr), 0);
408  _rm = o._rm;
409  _addr = o.release();
410  }
411  return *this;
412  }
413 
414  ~Unique_region() noexcept
415  {
416  if (_rm.is_valid())
417  _rm->detach(l4_addr_t(_addr), 0);
418  }
419 
420  T get() const noexcept
421  { return _addr; }
422 
423  T release() noexcept
424  {
425  _rm = L4::Cap<Rm>::Invalid;
426  return _addr;
427  }
428 
429  void reset(T addr, L4::Cap<Rm> const &rm) noexcept
430  {
431  if (_rm.is_valid())
432  _rm->detach(l4_addr_t(_addr), 0);
433 
434  _rm = rm;
435  _addr = addr;
436  }
437 
438  void reset() noexcept
439  { reset(0, L4::Cap<Rm>::Invalid); }
440 
441  bool is_valid() const noexcept
442  { return _rm.is_valid(); }
443 
445  T operator * () const noexcept { return _addr; }
446 
448  T operator -> () const noexcept { return _addr; }
449  };
450 
451  template< typename T >
452  long attach(Unique_region<T> *start, unsigned long size, Flags flags,
453  L4::Ipc::Cap<Dataspace> mem, Offset offs = 0,
454  unsigned char align = L4_PAGESHIFT) const noexcept
455  {
456  l4_addr_t addr = (l4_addr_t)start->get();
457 
458  long res = attach(&addr, size, flags, mem, offs, align);
459  if (res < 0)
460  return res;
461 
462  start->reset((T)addr, L4::Cap<Rm>(cap()));
463  return res;
464  }
465 #endif
466 
484  int detach(l4_addr_t addr, L4::Cap<Dataspace> *mem,
485  L4::Cap<L4::Task> const &task = This_task) const noexcept;
486 
490  int detach(void *addr, L4::Cap<Dataspace> *mem,
491  L4::Cap<L4::Task> const &task = This_task) const noexcept;
492 
512  int detach(l4_addr_t start, unsigned long size, L4::Cap<Dataspace> *mem,
513  L4::Cap<L4::Task> const &task) const noexcept;
514 
559  int find(l4_addr_t *addr, unsigned long *size, Offset *offset,
560  L4Re::Rm::Flags *flags, L4::Cap<Dataspace> *m) noexcept
561  { return find_t::call(c(), addr, size, flags, offset, m); }
562 
563  L4_RPC_NF(int, find, (L4::Ipc::In_out<l4_addr_t *> addr,
565  L4Re::Rm::Flags *flags, Offset *offset,
567 
571  struct Range
572  {
577  };
578 
584  using Region = Range;
585 
592  using Area = Range;
593 
608  L4_RPC(long, get_regions, (l4_addr_t start, L4::Ipc::Ret_array<Range> regions));
609 
625  L4_RPC(long, get_areas, (l4_addr_t start, L4::Ipc::Ret_array<Range> areas));
626 
627  int detach(l4_addr_t start, unsigned long size, L4::Cap<Dataspace> *mem,
628  L4::Cap<L4::Task> task, unsigned flags) const noexcept;
629 
630  typedef L4::Typeid::Rpcs<attach_t, detach_t, find_t,
631  reserve_area_t, free_area_t,
632  get_regions_t, get_areas_t> Rpcs;
633 };
634 
635 
636 inline int
638  L4::Cap<L4::Task> const &task) const noexcept
639 { return detach(addr, 1, mem, task, Detach_overlap); }
640 
641 inline int
643  L4::Cap<L4::Task> const &task) const noexcept
644 { return detach((l4_addr_t)addr, 1, mem, task, Detach_overlap); }
645 
646 inline int
647 Rm::detach(l4_addr_t addr, unsigned long size, L4::Cap<Dataspace> *mem,
648  L4::Cap<L4::Task> const &task) const noexcept
649 { return detach(addr, size, mem, task, Detach_exact); }
650 
651 };
#define L4_PAGESHIFT
Size of a page, log2-based.
Definition: consts.h:37
L4::Cap related definitions.
Region map.
Definition: rm:76
int find(l4_addr_t *addr, unsigned long *size, Offset *offset, L4Re::Rm::Flags *flags, L4::Cap< Dataspace > *m) noexcept
Find a region given an address and size.
Definition: rm:559
Detach_result
Result values for detach operation.
Definition: rm:82
long reserve_area(T **start, unsigned long size, Flags flags=Flags(0), unsigned char align=L4_PAGESHIFT) const noexcept
Reserve the given area in the region map.
Definition: rm:284
Region_flag_shifts
Definition: rm:93
long attach(T **start, unsigned long size, Flags flags, L4::Ipc::Cap< Dataspace > mem, Offset offs=0, unsigned char align=L4_PAGESHIFT) const noexcept
Attach a data space to a region.
Definition: rm:369
Detach_flags
Flags for detach operation.
Definition: rm:201
long reserve_area(l4_addr_t *start, unsigned long size, Flags flags=Flags(0), unsigned char align=L4_PAGESHIFT) const noexcept
Reserve the given area in the region map.
Definition: rm:258
int detach(l4_addr_t addr, L4::Cap< Dataspace > *mem, L4::Cap< L4::Task > const &task=This_task) const noexcept
Detach a region from the address space.
Definition: rm:637
bool is_valid() const noexcept
Test whether the capability is a valid capability index (i.e., not L4_INVALID_CAP).
Definition: capability.h:60
C++ interface for capabilities.
Definition: capability.h:219
Capability type for RPC interfaces (see L4::Cap<T>).
Definition: ipc_types:542
Helper class to create an L4Re interface class that is derived from a single base class.
Definition: __typeinfo.h:760
Dataspace interface.
unsigned long l4_addr_t
Address type.
Definition: l4int.h:45
unsigned int l4_uint32_t
Unsigned 32bit value.
Definition: l4int.h:40
unsigned short int l4_uint16_t
Unsigned 16bit value.
Definition: l4int.h:38
unsigned long l4_cap_idx_t
L4 Capability selector Type.
Definition: types.h:342
@ L4_FPAGE_X
Executable flex page.
Definition: __l4_fpage.h:111
@ L4_FPAGE_RO
Read-only flex page
Definition: __l4_fpage.h:113
@ L4_FPAGE_W
Writable flex page.
Definition: __l4_fpage.h:112
@ L4_CAP_FPAGE_RO
Read right for capability flex-pages.
Definition: __l4_fpage.h:162
@ L4_CAP_FPAGE_RW
Read and interface specific 'W' right for capability flex-pages.
Definition: __l4_fpage.h:178
Interface Definition Language.
#define L4_RPC(res, name, args, attr...)
Define an RPC call (type and callable).
Definition: ipc_iface:528
#define L4_RPC_NF(res, name, args...)
Define an RPC call type (the type only, no callable).
Definition: ipc_iface:497
Common L4 ABI Data Types.
L4Re C++ Interfaces.
Definition: cmd_control:15
L4 low-level kernel interface.
Pager and Io_pager C++ interface.
L4Re Protocol Constants (C version)
Constants.
@ Uncacheable
request uncacheable memory mappings
Definition: dataspace:100
@ RW
Request writable mapping (R + W)
Definition: dataspace:84
@ Normal
request normal memory mapping
Definition: dataspace:94
@ Caching_mask
mask for caching flags
Definition: dataspace:102
@ R
Request read-only mapping.
Definition: dataspace:80
@ W
Request write-only memory.
Definition: dataspace:86
@ Bufferable
request bufferable (write buffered) mappings
Definition: dataspace:98
@ Caching_shift
shift value for caching flags
Definition: dataspace:71
Rm flags definitions.
Definition: rm:100
Region_flags
Definition: rm:117
Attach_flags
Flags for attach operation.
Definition: rm:103
A range of virtual addresses.
Definition: rm:572
l4_addr_t start
First address of the range.
Definition: rm:574
l4_addr_t end
Last address of the range.
Definition: rm:576
Pass the argument as plain data value.
Definition: ipc_types:128
Mark an argument as in-out argument.
Definition: ipc_types:53
Attribute for defining an optional RPC argument.
Definition: ipc_types:148
Dynamically sized output array of type T.
Definition: ipc_ret_array:35
List of RPCs of an interface using a single operation without an opcode.
Definition: __typeinfo.h:464
Standard list of RPCs of an interface.
Definition: __typeinfo.h:438
Mixin class to define a set of friend bitwise operators on DT.
Definition: types:233
#define L4_TYPES_FLAGS_OPS_DEF(T)
Helper macro to define a set of bitwise operators on an enum type.
Definition: types:207