1// -*- Mode: C++ -*- 2// vim:ft=cpp 3/** 4 * \file 5 * Dataspace interface. 6 */ 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 28#pragma once 29 30#include <l4/sys/types.h> 31#include <l4/sys/l4int.h> 32#include <l4/sys/capability> 33#include <l4/re/protocols.h> 34#include <l4/sys/cxx/ipc_types> 35#include <l4/sys/cxx/ipc_iface> 36#include <l4/sys/cxx/types> 37 38namespace L4Re 39{ 40 41 // MISSING: 42 // * size support in map, mapped size in reply 43 44/** 45 * Interface for memory-like objects. 46 * 47 * Dataspaces are a central abstraction provided by L4Re. A dataspace is 48 * an abstraction for any thing that is available via usual memory access 49 * instructions. A dataspace can be a file, as well as the memory-mapped 50 * registers of a device, or anonymous memory, such as a heap. 51 * 52 * The dataspace interface defines a set of methods that allow any kind 53 * of dataspace to be attached (mapped) to the virtual address space of 54 * an L4 task and then be accessed via memory-access instructions. 55 * The L4Re::Rm interface can be used to attach a dataspace to a 56 * virtual address space of a task paged by a certain instance of a region map. 57 * 58 * \includefile{l4/re/dataspace} 59 */ 60class L4_EXPORT Dataspace : 61 public L4::Kobject_t<Dataspace, L4::Kobject, L4RE_PROTO_DATASPACE, 62 L4::Type_info::Demand_t<1> > 63{ 64public: 65 66 /** Dataspace flags definitions. */ 67 struct F 68 { 69 enum 70 { 71 Caching_shift = 4, ///< shift value for caching flags 72 }; 73 74 /** 75 * Flags for map operations. 76 */ 77 enum Flags 78 { 79 /// Request read-only mapping. 80 R = L4_FPAGE_RO, 81 /// Request read-only mapping. 82 Ro = L4_FPAGE_RO, 83 /// Request writable mapping (R + W) 84 RW = L4_FPAGE_RW, 85 /// Request write-only memory 86 W = L4_FPAGE_W, 87 X = L4_FPAGE_X, 88 RX = L4_FPAGE_RX, 89 RWX = L4_FPAGE_RWX, 90 /// All rights bits available for mappings 91 Rights_mask = 0x0f, 92 93 /// request normal memory mapping 94 Normal = 0x00, 95 /// request normal memory mapping 96 Cacheable = Normal, 97 /// request bufferable (write buffered) mappings 98 Bufferable = 0x10, 99 /// request uncacheable memory mappings 100 Uncacheable = 0x20, 101 /// mask for caching flags 102 Caching_mask = 0x30, 103 }; 104 105 L4_TYPES_FLAGS_OPS_DEF(Flags); 106 }; 107 108 struct Flags : L4::Types::Flags_ops_t<Flags> 109 { 110 unsigned long raw; 111 Flags() = default; 112 explicit constexpr Flags(unsigned long f) : raw(f) {} 113 constexpr Flags(F::Flags f) : raw(f) {} 114 constexpr bool r() const { return raw & L4_FPAGE_RO; } 115 constexpr bool w() const { return raw & L4_FPAGE_W; } 116 constexpr bool x() const { return raw & L4_FPAGE_X; } 117 118 constexpr unsigned long fpage_rights() const 119 { return raw & 0xf; } 120 }; 121 122 typedef l4_uint64_t Size; 123 typedef l4_uint64_t Offset; 124 typedef l4_uint64_t Map_addr; 125 126 /** 127 * Information about the dataspace. 128 */ 129 struct Stats 130 { 131 Size size; ///< size 132 Flags flags; ///< flags 133 }; 134 135 136 /** 137 * Request a flex-page mapping from the dataspace. 138 * 139 * \param offset Offset to start within dataspace 140 * \param flags Dataspace flags, see #L4Re::Dataspace::F::Flags. 141 * \param local_addr Local address to map to. 142 * \param min_addr Defines start of receive window. 143 * (Rounded down to page size.) 144 * \param max_addr Defines end of receive window. 145 * (Rounded up to page size.) 146 * 147 * \retval L4_EOK Success 148 * \retval -L4_ERANGE Invalid offset. 149 * \retval -L4_EPERM Insufficient permission to map with requested rights. 150 * \retval <0 IPC errors 151 * 152 * The map call will attempt to map the largest possible flexpage that 153 * covers the given local address and still fits into the region 154 * defined by `min_addr` and `max_addr`. If the given region is 155 * invalid or does not overlap the local address, the smallest valid 156 * page size is used. 157 */ 158 long map(Offset offset, Flags flags, Map_addr local_addr, 159 Map_addr min_addr, Map_addr max_addr) const noexcept; 160 161 /** 162 * Map a part of a dataspace into a local memory area. 163 * 164 * \param offset Offset to start within dataspace. 165 * \param flags Dataspace flags, see #L4Re::Dataspace::F::Flags. 166 * \param min_addr (Inclusive) start of the receive area. 167 * \param max_addr (Exclusive) end of receive area. 168 * 169 * \retval L4_EOK Success 170 * \retval -L4_ERANGE Invalid offset or receive area larger than 171 * the dataspace. 172 * \retval -L4_EPERM Insufficient permission to map with requested rights. 173 * \retval <0 IPC errors 174 * 175 * This is a convenience function which maps flex-pages consecutively into 176 * the given memory area in the local task. The area is expected to be filled 177 * completely. If the dataspace is not large enough to provide the mappings 178 * for the entire size of the area, then an error is returned. Mappings may 179 * or may not have been already established at that point. 180 * 181 * `offset` and `min_addr` are rounded down to the 182 * next `L4_PAGESIZE` boundary when necessary. `max_addr` is rounded up 183 * to the page boundary. If the resulting maximum address is less or equal 184 * than the minimum address, then the function is a noop. 185 */ 186 long map_region(Offset offset, Flags flags, 187 Map_addr min_addr, Map_addr max_addr) const noexcept; 188 189 /** 190 * Clear parts of a dataspace. 191 * 192 * \param offset Offset within dataspace (in bytes). 193 * \param size Size of region to clear (in bytes). 194 * 195 * \retval >=0 Success. 196 * \retval -L4_ERANGE Given range is outside the dataspace. 197 * (A dataspace provider may also silently ignore areas 198 * outside the dataspace.) 199 * \retval -L4_EACCESS Dataspace is read-only. 200 * \retval <0 IPC errors 201 * 202 * Zeroes out the memory. Depending on the type of memory 203 * the memory could also be deallocated and replaced by 204 * a shared zero-page. 205 */ 206 L4_RPC(long, clear, (Offset offset, Size size)); 207 208 /** 209 * Allocate a range in the dataspace. 210 * 211 * \param offset Offset in the dataspace, in bytes. 212 * \param size Size of the range, in bytes. 213 * 214 * \retval L4_EOK Success 215 * \retval -L4_ERANGE Given range is outside the dataspace. 216 * (A dataspace provider may also silently ignore areas 217 * outside the dataspace.) 218 * \retval -L4_ENOMEM Not enough memory available. 219 * \retval <0 IPC errors 220 * 221 * On success, at least the given range is guaranteed to be allocated. The 222 * dataspace manager may also allocate more memory due to page granularity. 223 * 224 * The memory is allocated with the same rights as the dataspace 225 * capability. 226 */ 227 L4_RPC(long, allocate, (Offset offset, Size size)); 228 229 /** 230 * Copy contents from another dataspace. 231 * 232 * \param dst_offs Offset in destination dataspace. 233 * \param src Source dataspace to copy from. 234 * \param src_offs Offset in the source dataspace. 235 * \param size Size to copy (in bytes). 236 * 237 * \retval L4_EOK Success 238 * \retval -L4_EACCESS Destination dataspace not writable. 239 * \retval -L4_EINVAL Invalid parameter supplied. 240 * \retval <0 IPC errors 241 * 242 * The copy operation may use copy-on-write mechanisms. The operation may 243 * also fail if both dataspaces are not from the same dataspace manager 244 * or the dataspace managers do not cooperate. 245 */ 246 L4_RPC(long, copy_in, (Offset dst_offs, L4::Ipc::Cap<Dataspace> src, 247 Offset src_offs, Size size)); 248 249 /** 250 * Get size of a dataspace. 251 * 252 * \return Size of the dataspace in bytes. 253 */ 254 Size size() const noexcept; 255 256 /** 257 * Get flags of the dataspace. 258 * 259 * \retval >=0 Flags of the dataspace 260 * \retval <0 IPC errors 261 * 262 * \see L4Re::Dataspace::F::Flags 263 */ 264 Flags flags() const noexcept; 265 266 /** 267 * Get information on the dataspace. 268 * 269 * \param[out] stats Dataspace information 270 * 271 * \retval 0 Success 272 * \retval <0 IPC errors 273 */ 274 L4_RPC(long, info, (Stats *stats)); 275 276 L4_RPC_NF(long, map, (Offset offset, Map_addr spot, 277 Flags flags, L4::Ipc::Rcv_fpage r, 278 L4::Ipc::Snd_fpage &fp)); 279 280private: 281 282 long __map(Offset offset, unsigned char *order, Flags flags, 283 Map_addr local_addr) const noexcept; 284 285public: 286 typedef L4::Typeid::Rpcs<map_t, clear_t, info_t, copy_in_t, 287 allocate_t> Rpcs; 288 289}; 290 291} 292 293