L4Re - L4 Runtime Environment
dataspace_svr
1 // vi:set ft=cpp: -*- Mode: C++ -*-
2 /*
3  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
4  * Alexander Warg <warg@os.inf.tu-dresden.de>,
5  * Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
6  * economic rights: Technische Universität Dresden (Germany)
7  *
8  * This file is part of TUD:OS and distributed under the terms of the
9  * GNU General Public License 2.
10  * Please see the COPYING-GPL-2 file for details.
11  *
12  * As a special exception, you may use this file as part of a free software
13  * library without restriction. Specifically, if other files instantiate
14  * templates or use macros or inline functions from this file, or you compile
15  * this file and link it with other files to produce an executable, this
16  * file does not by itself cause the resulting executable to be covered by
17  * the GNU General Public License. This exception does not however
18  * invalidate any other reasons why the executable file might be covered by
19  * the GNU General Public License.
20  */
21 #pragma once
22 
23 #include <cstring>
24 #include <cstddef>
25 #include <l4/sys/types.h>
26 #include <l4/cxx/list>
27 #include <l4/cxx/minmax>
28 #include <l4/re/dataspace>
29 #include <l4/re/dataspace-sys.h>
30 #include <l4/sys/cxx/ipc_legacy>
31 
32 namespace L4Re { namespace Util {
33 
41 {
42 private:
44 public:
45  L4_RPC_LEGACY_DISPATCH(L4Re::Dataspace);
46 
49  enum Rw_type {
50  Read_only = 0,
51  Writable = 1,
52  };
53 
54 
55  Dataspace_svr() throw()
56  : _ds_start(0), _ds_size(0), _map_flags(Snd_fpage::Map),
57  _cache_flags(Snd_fpage::Cached)
58  {}
59 
60  virtual ~Dataspace_svr() throw() {}
61 
75  int map(l4_addr_t offset, l4_addr_t local_addr, unsigned long flags,
76  l4_addr_t min_addr, l4_addr_t max_addr, L4::Ipc::Snd_fpage &memory);
77 
90  virtual int map_hook(l4_addr_t offs, unsigned long flags,
92  {
93  (void)offs; (void)flags; (void)min; (void)max;
94  return 0;
95  }
96 
107  virtual int phys(l4_addr_t offset, l4_addr_t &phys_addr, l4_size_t &phys_size) throw();
108 
114  virtual void take() throw()
115  {}
116 
124  virtual unsigned long release() throw()
125  { return 0; }
126 
139  virtual long copy(l4_addr_t dst_offs, l4_umword_t src_id,
140  l4_addr_t src_offs, unsigned long size) throw()
141  {
142  (void)dst_offs; (void)src_id; (void)src_offs; (void)size;
143  return -L4_ENODEV;
144  }
145 
155  virtual long clear(unsigned long offs, unsigned long size) const throw();
156 
168  virtual long allocate(l4_addr_t offset, l4_size_t size, unsigned access) throw()
169  { (void)offset; (void)size; (void)access; return -L4_ENODEV; }
170 
176  virtual unsigned long page_shift() const throw()
177  { return L4_LOG2_PAGESIZE; }
178 
184  virtual bool is_static() const throw()
185  { return true; }
186 
187 
188  long op_map(L4Re::Dataspace::Rights rights,
189  unsigned long offset, l4_addr_t spot,
190  unsigned long flags, L4::Ipc::Snd_fpage &fp)
191  {
192  bool read_only = !is_writable() || !(rights & L4_CAP_FPAGE_W);
193 
194  if (read_only && (flags & 1))
195  return -L4_EPERM;
196 
197  return map(offset, spot, flags & 1, 0, ~0, fp);
198  }
199 
200  long op_take(L4Re::Dataspace::Rights)
201  { take(); return 0; }
202 
203  long op_release(L4Re::Dataspace::Rights)
204  {
205 
206  if (release() == 0 && !is_static())
207  {
208  //L4::cout << "MOE: R[" << this << "]: refs=" << ref_cnt() << '\n';
209  delete this;
210  return 0;
211  }
212  //L4::cout << "MOE: R[" << this << "]: refs=" << ref_cnt() << '\n';
213 
214  return 1;
215  }
216 
217  long op_allocate(L4Re::Dataspace::Rights rights,
218  l4_addr_t offset, l4_size_t size)
219  { return allocate(offset, size, rights & 3); }
220 
221  long op_copy_in(L4Re::Dataspace::Rights rights,
222  l4_addr_t dst_offs, L4::Ipc::Snd_fpage const &src_cap,
223  l4_addr_t src_offs, unsigned long sz)
224  {
225  if (!src_cap.id_received())
226  return -L4_EINVAL;
227 
228  if (!(rights & L4_CAP_FPAGE_W))
229  return -L4_EACCESS;
230 
231  if (sz == 0)
232  return L4_EOK;
233 
234  return copy(dst_offs, src_cap.data(), src_offs, sz);
235  }
236 
237  long op_phys(L4Re::Dataspace::Rights, l4_addr_t offset,
238  l4_addr_t &phys_addr, l4_size_t &phys_size)
239  { return phys(offset, phys_addr, phys_size); }
240 
241  long op_info(L4Re::Dataspace::Rights rights, L4Re::Dataspace::Stats &s)
242  {
243  s.size = size();
244  // only return writable if really writable
245  s.flags = rw_flags() & ~Writable;
246  if ((rights & L4_CAP_FPAGE_W) && is_writable())
247  s.flags |= Writable;
248  return L4_EOK;
249  }
250 
251  long op_clear(L4Re::Dataspace::Rights rights,
252  l4_addr_t offset, unsigned long size)
253  {
254  if ( !(rights & L4_CAP_FPAGE_W)
255  || !is_writable())
256  return -L4_EACCESS;
257 
258  return clear(offset, size);
259  }
260 
261 
262 protected:
263  unsigned long size() const throw()
264  { return _ds_size; }
265  unsigned long map_flags() const throw()
266  { return _map_flags; }
267  unsigned long rw_flags() const throw()
268  { return _rw_flags; }
269  unsigned long is_writable() const throw()
270  { return _rw_flags & Writable; }
271  unsigned long page_size() const throw()
272  { return 1UL << page_shift(); }
273  unsigned long round_size() const throw()
274  { return l4_round_size(size(), page_shift()); }
275  bool check_limit(l4_addr_t offset) const throw()
276  { return offset < round_size(); }
277 
278 protected:
279  void size(unsigned long size) throw() { _ds_size = size; }
280 
281  l4_addr_t _ds_start;
282  l4_size_t _ds_size;
283  Map_type _map_flags;
284  Cache_type _cache_flags;
285  Rw_type _rw_flags;
286 };
287 
288 }}
unsigned int l4_size_t
Unsigned size type.
Definition: l4int.h:35
unsigned long size
size
Definition: dataspace:86
No such thing.
Definition: err.h:55
virtual unsigned long page_shift() const
Define the size of the flexpage to map.
Definition: dataspace_svr:176
No permission.
Definition: err.h:44
Invalid argument.
Definition: err.h:56
Interface specific &#39;W&#39; right for capability flex-pages.
Definition: __l4_fpage.h:143
Common L4 ABI Data Types.
Information about the dataspace.
Definition: dataspace:85
l4_addr_t l4_round_size(l4_umword_t value, unsigned char bits) L4_NOTHROW
Round value up to the next alignment with bits size.
Definition: consts.h:400
Dataspace protocol defintion.
L4Re C++ Interfaces.
Definition: cmd_control:15
Permission denied.
Definition: err.h:51
Cacheopt
Caching options, see l4_fpage_cacheability_opt_t.
Definition: ipc_types:341
Interface for memory-like objects.
Definition: dataspace:59
T1 max(T1 a, T1 b)
Get the maximum of a and b.
Definition: minmax:46
#define L4_LOG2_PAGESIZE
Number of bits used for page offset.
Definition: consts.h:325
virtual int phys(l4_addr_t offset, l4_addr_t &phys_addr, l4_size_t &phys_size)
Return physical address for a virtual address.
Ok.
Definition: err.h:43
l4_umword_t data() const
Return the raw flex page descriptor.
Definition: ipc_types:470
unsigned long flags
flags
Definition: dataspace:87
Dataspace server class.
Definition: dataspace_svr:40
virtual bool is_static() const
Return whether the dataspace is static.
Definition: dataspace_svr:184
virtual void take()
Take a reference to this dataspace.
Definition: dataspace_svr:114
unsigned long l4_umword_t
Unsigned machine word.
Definition: l4int.h:52
Map_type
Kind of mapping.
Definition: ipc_types:334
virtual long copy(l4_addr_t dst_offs, l4_umword_t src_id, l4_addr_t src_offs, unsigned long size)
Copy from src dataspace to this destination dataspace.
Definition: dataspace_svr:139
int map(l4_addr_t offset, l4_addr_t local_addr, unsigned long flags, l4_addr_t min_addr, l4_addr_t max_addr, L4::Ipc::Snd_fpage &memory)
Map a region of the dataspace.
virtual long clear(unsigned long offs, unsigned long size) const
Clear a region in the dataspace.
Dataspace interface.
virtual unsigned long release()
Release a reference to this dataspace.
Definition: dataspace_svr:124
unsigned long l4_addr_t
Address type.
Definition: l4int.h:45
bool id_received() const
Check if a label was received instead of a mapping.
Definition: ipc_types:450
virtual long allocate(l4_addr_t offset, l4_size_t size, unsigned access)
Allocate a region within a dataspace.
Definition: dataspace_svr:168
T1 min(T1 a, T1 b)
Get the minimum of a and b.
Definition: minmax:35
Generic RPC wrapper for L4 flex-pages.
Definition: ipc_types:321
virtual int map_hook(l4_addr_t offs, unsigned long flags, l4_addr_t min, l4_addr_t max)
A hook that is called as the first operation in each map request.
Definition: dataspace_svr:90