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/re/consts>
37 #include <l4/re/dataspace>
38 
39 namespace L4Re {
40 
71 class L4_EXPORT Rm :
72  public L4::Kobject_t<Rm, L4::Pager, L4RE_PROTO_RM,
73  L4::Type_info::Demand_t<1> >
74 {
75 public:
78  {
79  Detached_ds = 0,
80  Kept_ds = 1,
81  Split_ds = 2,
82  Detach_result_mask = 3,
83 
84  Detach_again = 4,
85  };
86 
89  {
90  Read_only = 0x01,
91  Detach_free = 0x02,
93  Pager = 0x04,
94  Reserved = 0x08,
95 
97  Caching_shift = 8,
99  Caching_ds_shift = Caching_shift - Dataspace::Map_caching_shift,
101  Caching = Dataspace::Map_caching_mask << Caching_ds_shift,
103  Cache_normal = Dataspace::Map_normal << Caching_ds_shift,
105  Cache_buffered = Dataspace::Map_bufferable << Caching_ds_shift,
107  Cache_uncached = Dataspace::Map_uncacheable << Caching_ds_shift,
108 
109  Region_flags = Caching | 0x0f,
110  };
111 
114  {
115  Search_addr = 0x20,
116  In_area = 0x40,
117  Eager_map = 0x80,
118 
119  Attach_flags = 0xf0,
120  };
121 
124  {
134  Detach_exact = 1,
144  Detach_overlap = 2,
145 
153  Detach_keep = 4,
154  };
155 
156 
157  template< typename T >
158  class Auto_region
159  {
160  private:
161  T _addr;
162  mutable L4::Cap<Rm> _rm;
163 
164  public:
165  Auto_region() throw()
166  : _addr(0), _rm(L4::Cap<Rm>::Invalid) {}
167 
168  explicit Auto_region(T addr) throw()
169  : _addr(addr), _rm(L4::Cap<Rm>::Invalid) {}
170 
171  Auto_region(T addr, L4::Cap<Rm> const &rm) throw()
172  : _addr(addr), _rm(rm) {}
173 
174  Auto_region(Auto_region const &o) throw() : _addr(o.get()), _rm(o._rm)
175  { o.release(); }
176 
177  Auto_region &operator = (Auto_region const &o) throw()
178  {
179  if (&o != this)
180  {
181  if (_rm.is_valid())
182  _rm->detach(l4_addr_t(_addr), 0);
183  _rm = o._rm;
184  _addr = o.release();
185  }
186  return *this;
187  }
188 
189  ~Auto_region() throw()
190  {
191  if (_rm.is_valid())
192  _rm->detach(l4_addr_t(_addr), 0);
193  }
194 
195  T get() const throw() { return _addr; }
196  T release() const throw() { _rm = L4::Cap<Rm>::Invalid; return _addr; }
197  void reset(T addr, L4::Cap<Rm> const &rm) throw()
198  {
199  if (_rm.is_valid())
200  _rm->detach(l4_addr_t(_addr), 0);
201 
202  _rm = rm;
203  _addr = addr;
204  }
205 
206  void reset() throw()
207  { reset(0, L4::Cap<Rm>::Invalid); }
208 
210  T operator * () const throw() { return _addr; }
211 
213  T operator -> () const throw() { return _addr; }
214 
215  } L4_DEPRECATED("use L4Re::Rm::Unique_region");
216 
241  long reserve_area(l4_addr_t *start, unsigned long size,
242  unsigned flags = 0,
243  unsigned char align = L4_PAGESHIFT) const throw()
244  { return reserve_area_t::call(c(), start, size, flags, align); }
245 
246  L4_RPC_NF(long, reserve_area, (L4::Ipc::In_out<l4_addr_t *> start,
247  unsigned long size,
248  unsigned flags,
249  unsigned char align));
250 
266  template< typename T >
267  long reserve_area(T **start, unsigned long size,
268  unsigned flags = 0,
269  unsigned char align = L4_PAGESHIFT) const throw()
270  { return reserve_area_t::call(c(), (l4_addr_t*)start, size, flags, align); }
271 
284  L4_RPC(long, free_area, (l4_addr_t addr));
285 
286  L4_RPC_NF(long, attach, (L4::Ipc::In_out<l4_addr_t *> start,
287  unsigned long size, unsigned long flags,
289  l4_addr_t offs, unsigned char align,
290  L4::Ipc::Opt<l4_cap_idx_t> client_cap));
291 
292  L4_RPC_NF(long, detach, (l4_addr_t addr, unsigned long size, unsigned flags,
293  l4_addr_t &start, l4_addr_t &rsize,
294  l4_cap_idx_t &mem_cap));
295 
339  long attach(l4_addr_t *start, unsigned long size, unsigned long flags,
340  L4::Ipc::Cap<Dataspace> mem, l4_addr_t offs = 0,
341  unsigned char align = L4_PAGESHIFT) const throw();
342 
346  template< typename T >
347  long attach(T **start, unsigned long size, unsigned long flags,
348  L4::Ipc::Cap<Dataspace> mem, l4_addr_t offs = 0,
349  unsigned char align = L4_PAGESHIFT) const throw()
350  {
351  union X { l4_addr_t a; T* t; };
352  X *x = reinterpret_cast<X*>(start);
353  return attach(&x->a, size, flags, mem, offs, align);
354  }
355 
356 #pragma GCC diagnostic push
357 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
358  template< typename T >
359  long attach(Auto_region<T> *start, unsigned long size, unsigned long flags,
360  L4::Ipc::Cap<Dataspace> mem, l4_addr_t offs = 0,
361  unsigned char align = L4_PAGESHIFT) const throw()
362  {
363  l4_addr_t addr = (l4_addr_t)start->get();
364 
365  long res = attach(&addr, size, flags, mem, offs, align);
366  if (res < 0)
367  return res;
368 
369  start->reset((T)addr, L4::Cap<Rm>(cap()));
370  return res;
371  }
372 #pragma GCC diagnostic pop
373 
374 #if __cplusplus >= 201103L
375  template< typename T >
376  class Unique_region
377  {
378  private:
379  T _addr;
380  L4::Cap<Rm> _rm;
381 
382  public:
383  Unique_region(Unique_region const &) = delete;
384  Unique_region &operator = (Unique_region const &) = delete;
385 
386  Unique_region() noexcept
387  : _addr(0), _rm(L4::Cap<Rm>::Invalid) {}
388 
389  explicit Unique_region(T addr) noexcept
390  : _addr(addr), _rm(L4::Cap<Rm>::Invalid) {}
391 
392  Unique_region(T addr, L4::Cap<Rm> const &rm) noexcept
393  : _addr(addr), _rm(rm) {}
394 
395  Unique_region(Unique_region &&o) noexcept : _addr(o.get()), _rm(o._rm)
396  { o.release(); }
397 
398  Unique_region &operator = (Unique_region &&o) noexcept
399  {
400  if (&o != this)
401  {
402  if (_rm.is_valid())
403  _rm->detach(l4_addr_t(_addr), 0);
404  _rm = o._rm;
405  _addr = o.release();
406  }
407  return *this;
408  }
409 
410  ~Unique_region() noexcept
411  {
412  if (_rm.is_valid())
413  _rm->detach(l4_addr_t(_addr), 0);
414  }
415 
416  T get() const noexcept
417  { return _addr; }
418 
419  T release() noexcept
420  {
421  _rm = L4::Cap<Rm>::Invalid;
422  return _addr;
423  }
424 
425  void reset(T addr, L4::Cap<Rm> const &rm) noexcept
426  {
427  if (_rm.is_valid())
428  _rm->detach(l4_addr_t(_addr), 0);
429 
430  _rm = rm;
431  _addr = addr;
432  }
433 
434  void reset() noexcept
435  { reset(0, L4::Cap<Rm>::Invalid); }
436 
437  bool is_valid() const noexcept
438  { return _rm.is_valid(); }
439 
441  T operator * () const noexcept { return _addr; }
442 
444  T operator -> () const noexcept { return _addr; }
445  };
446 
447  template< typename T >
448  long attach(Unique_region<T> *start, unsigned long size, unsigned long flags,
449  L4::Ipc::Cap<Dataspace> mem, l4_addr_t offs = 0,
450  unsigned char align = L4_PAGESHIFT) const noexcept
451  {
452  l4_addr_t addr = (l4_addr_t)start->get();
453 
454  long res = attach(&addr, size, flags, mem, offs, align);
455  if (res < 0)
456  return res;
457 
458  start->reset((T)addr, L4::Cap<Rm>(cap()));
459  return res;
460  }
461 #endif
462 
480  int detach(l4_addr_t addr, L4::Cap<Dataspace> *mem,
481  L4::Cap<L4::Task> const &task = This_task) const throw();
482 
486  int detach(void *addr, L4::Cap<Dataspace> *mem,
487  L4::Cap<L4::Task> const &task = This_task) const throw();
488 
508  int detach(l4_addr_t start, unsigned long size, L4::Cap<Dataspace> *mem,
509  L4::Cap<L4::Task> const &task) const throw();
510 
555  int find(l4_addr_t *addr, unsigned long *size, l4_addr_t *offset,
556  unsigned *flags, L4::Cap<Dataspace> *m) throw()
557  { return find_t::call(c(), addr, size, flags, offset, m); }
558 
559  L4_RPC_NF(int, find, (L4::Ipc::In_out<l4_addr_t *> addr,
561  unsigned *flags, l4_addr_t *offset,
563 
564  struct Region
565  {
566  l4_addr_t start;
567  l4_addr_t end;
568  l4_addr_t offset;
570  };
571 
572  struct Area
573  {
574  l4_addr_t start;
575  l4_addr_t end;
576  };
577 
578  L4_RPC(long, get_regions, (l4_addr_t start, L4::Ipc::Ret_array<Region> regions));
579  L4_RPC(long, get_areas, (l4_addr_t start, L4::Ipc::Ret_array<Area> areas));
580 
581  int detach(l4_addr_t start, unsigned long size, L4::Cap<Dataspace> *mem,
582  L4::Cap<L4::Task> task, unsigned flags) const throw();
583 
584  typedef L4::Typeid::Rpcs<attach_t, detach_t, find_t,
585  reserve_area_t, free_area_t,
586  get_regions_t, get_areas_t> Rpcs;
587 };
588 
589 
590 inline int
592  L4::Cap<L4::Task> const &task) const throw()
593 { return detach(addr, 1, mem, task, Detach_overlap); }
594 
595 inline int
597  L4::Cap<L4::Task> const &task) const throw()
598 { return detach((l4_addr_t)addr, 1, mem, task, Detach_overlap); }
599 
600 inline int
601 Rm::detach(l4_addr_t addr, unsigned long size, L4::Cap<Dataspace> *mem,
602  L4::Cap<L4::Task> const &task) const throw()
603 { return detach(addr, size, mem, task, Detach_exact); }
604 
605 };
606 
Pager and Io_pager C++ interface.
Capability type for RPC interfaces (see L4::Cap<T>).
Definition: ipc_types:541
long reserve_area(l4_addr_t *start, unsigned long size, unsigned flags=0, unsigned char align=L4_PAGESHIFT) const
Reserve the given area in the region map.
Definition: rm:241
Constants.
Standard list of RPCs of an interface.
Definition: __typeinfo.h:438
Detach_flags
Flags for detach operation.
Definition: rm:123
mask for caching flags
Definition: dataspace:78
Common L4 ABI Data Types.
Pass the argument as plain data value.
Definition: ipc_types:127
shift value for caching flags
Definition: dataspace:79
request uncacheable memory mappings
Definition: dataspace:76
unsigned long l4_cap_idx_t
L4 Capability selector Type.
Definition: types.h:342
L4Re C++ Interfaces.
Definition: cmd_control:15
L4::Cap related definitions.
List of RPCs of an interface using a single operation without an opcode.
Definition: __typeinfo.h:464
long reserve_area(T **start, unsigned long size, unsigned flags=0, unsigned char align=L4_PAGESHIFT) const
Reserve the given area in the region map.
Definition: rm:267
int detach(l4_addr_t addr, L4::Cap< Dataspace > *mem, L4::Cap< L4::Task > const &task=This_task) const
Detach a region from the address space.
Definition: rm:591
request bufferable (write buffered) mappings
Definition: dataspace:75
request normal memory mapping
Definition: dataspace:73
Mark an argument as in-out argument.
Definition: ipc_types:52
Attach_flags
Flags for attach operation.
Definition: rm:113
Interface Definition Language.
Attribute for defining an optional RPC argument.
Definition: ipc_types:147
#define L4_PAGESHIFT
Size of a page, log2-based.
Definition: consts.h:37
long attach(T **start, unsigned long size, unsigned long flags, L4::Ipc::Cap< Dataspace > mem, l4_addr_t offs=0, unsigned char align=L4_PAGESHIFT) const
Attach a data space to a region.
Definition: rm:347
Region map.
Definition: rm:71
bool is_valid() const
Test whether the capability is a valid capability index (i.e., not L4_INVALID_CAP).
Definition: capability.h:60
int find(l4_addr_t *addr, unsigned long *size, l4_addr_t *offset, unsigned *flags, L4::Cap< Dataspace > *m)
Find a region given an address and size.
Definition: rm:555
Helper class to create an L4Re interface class that is derived from a single base class...
Definition: __typeinfo.h:759
Dataspace interface.
Detach_result
Result values for detach operation.
Definition: rm:77
Region_flags
Flags for regions.
Definition: rm:88
C++ interface for capabilities.
Definition: capability.h:13
L4Re Protocol Constants (C version)
unsigned long l4_addr_t
Address type.
Definition: l4int.h:45
#define L4_DEPRECATED(s)
Mark symbol deprecated.
Definition: compiler.h:239
#define L4_RPC(res, name, args, attr...)
Define an RPC call (type and callable).
Definition: ipc_iface:517
#define L4_RPC_NF(res, name, args...)
Define an RPC call type (the type only, no callable).
Definition: ipc_iface:486
Dynamically sized output array of type T.
Definition: ipc_ret_array:34