paul@515 | 1 | /* |
paul@515 | 2 | * Memory area support. |
paul@515 | 3 | * |
paul@515 | 4 | * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk> |
paul@515 | 5 | * |
paul@515 | 6 | * This program is free software; you can redistribute it and/or |
paul@515 | 7 | * modify it under the terms of the GNU General Public License as |
paul@515 | 8 | * published by the Free Software Foundation; either version 2 of |
paul@515 | 9 | * the License, or (at your option) any later version. |
paul@515 | 10 | * |
paul@515 | 11 | * This program is distributed in the hope that it will be useful, |
paul@515 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
paul@515 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
paul@515 | 14 | * GNU General Public License for more details. |
paul@515 | 15 | * |
paul@515 | 16 | * You should have received a copy of the GNU General Public License |
paul@515 | 17 | * along with this program; if not, write to the Free Software |
paul@515 | 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, |
paul@515 | 19 | * Boston, MA 02110-1301, USA |
paul@515 | 20 | */ |
paul@515 | 21 | |
paul@515 | 22 | #pragma once |
paul@515 | 23 | |
paul@515 | 24 | #include <map> |
paul@515 | 25 | #include <set> |
paul@515 | 26 | #include <stack> |
paul@515 | 27 | |
paul@515 | 28 | #include <l4/sys/types.h> |
paul@515 | 29 | |
paul@515 | 30 | #include <systypes/base.h> |
paul@515 | 31 | |
paul@515 | 32 | |
paul@515 | 33 | |
paul@515 | 34 | /* A memory area abstraction. */ |
paul@515 | 35 | |
paul@515 | 36 | class MemoryArea |
paul@515 | 37 | { |
paul@515 | 38 | protected: |
paul@515 | 39 | address_t _start, _end; |
paul@515 | 40 | |
paul@515 | 41 | public: |
paul@515 | 42 | explicit MemoryArea() |
paul@515 | 43 | : _start(0), _end(0) |
paul@515 | 44 | { |
paul@515 | 45 | } |
paul@515 | 46 | |
paul@515 | 47 | explicit MemoryArea(address_t start, address_t end) |
paul@515 | 48 | : _start(start), _end(end) |
paul@515 | 49 | { |
paul@515 | 50 | } |
paul@515 | 51 | |
paul@515 | 52 | virtual ~MemoryArea() |
paul@515 | 53 | { |
paul@515 | 54 | } |
paul@515 | 55 | |
paul@515 | 56 | virtual MemoryArea *copy(); |
paul@515 | 57 | |
paul@515 | 58 | /* Access to area properties. */ |
paul@515 | 59 | |
paul@515 | 60 | virtual address_t area_start() |
paul@515 | 61 | { return _start; } |
paul@515 | 62 | |
paul@515 | 63 | virtual address_t area_end() |
paul@515 | 64 | { return _end; } |
paul@515 | 65 | |
paul@515 | 66 | virtual l4_umword_t flags() |
paul@515 | 67 | { return 0; } |
paul@515 | 68 | |
paul@515 | 69 | virtual l4_cap_idx_t dataspace() |
paul@515 | 70 | { return L4_INVALID_CAP; } |
paul@515 | 71 | |
paul@515 | 72 | virtual address_t dataspace_start() |
paul@515 | 73 | { return 0; } |
paul@515 | 74 | |
paul@515 | 75 | /* Return whether the area supports the given address. */ |
paul@515 | 76 | |
paul@515 | 77 | virtual bool supports(address_t addr) |
paul@515 | 78 | { return (_start <= addr) && (addr < _end); } |
paul@515 | 79 | |
paul@515 | 80 | /* Return whether an area is reserved and therefore cannot be mapped. */ |
paul@515 | 81 | |
paul@515 | 82 | virtual bool is_reserved() |
paul@515 | 83 | { return false; } |
paul@515 | 84 | |
paul@515 | 85 | /* Return whether the area provides a mapped region. */ |
paul@515 | 86 | |
paul@515 | 87 | virtual bool is_mapped() |
paul@515 | 88 | { return false; } |
paul@515 | 89 | |
paul@515 | 90 | /* Support for populating areas. */ |
paul@515 | 91 | |
paul@515 | 92 | virtual long add(MemoryArea &area); |
paul@515 | 93 | |
paul@515 | 94 | virtual long remove(MemoryArea &area); |
paul@515 | 95 | |
paul@515 | 96 | /* Support for finding regions. */ |
paul@515 | 97 | |
paul@545 | 98 | virtual long find(address_t addr, MemoryArea **area, MemoryArea **parent); |
paul@515 | 99 | |
paul@515 | 100 | /* Support for finding areas. */ |
paul@515 | 101 | |
paul@515 | 102 | virtual long find(address_t *start, address_t *size, map_flags_t flags, |
paul@515 | 103 | unsigned char align, MemoryArea **area); |
paul@515 | 104 | }; |
paul@515 | 105 | |
paul@515 | 106 | |
paul@515 | 107 | |
paul@515 | 108 | /* A reserved area abstraction. */ |
paul@515 | 109 | |
paul@515 | 110 | class ReservedMemoryArea : public MemoryArea |
paul@515 | 111 | { |
paul@515 | 112 | public: |
paul@515 | 113 | explicit ReservedMemoryArea(address_t start, address_t end) |
paul@515 | 114 | : MemoryArea(start, end) |
paul@515 | 115 | { |
paul@515 | 116 | } |
paul@515 | 117 | |
paul@515 | 118 | virtual MemoryArea *copy(); |
paul@515 | 119 | |
paul@515 | 120 | /* Return whether an area is reserved and therefore cannot be mapped. */ |
paul@515 | 121 | |
paul@515 | 122 | virtual bool is_reserved() |
paul@515 | 123 | { return true; } |
paul@515 | 124 | |
paul@515 | 125 | /* Support for finding areas. */ |
paul@515 | 126 | |
paul@545 | 127 | virtual long find(address_t addr, MemoryArea **area, MemoryArea **parent); |
paul@515 | 128 | }; |
paul@515 | 129 | |
paul@515 | 130 | |
paul@515 | 131 | |
paul@515 | 132 | /* Collection types. */ |
paul@515 | 133 | |
paul@515 | 134 | typedef std::map<address_t, MemoryArea *> MemoryAreaMap; |
paul@515 | 135 | typedef std::set<MemoryArea *> MemoryAreas; |
paul@515 | 136 | |
paul@515 | 137 | |
paul@515 | 138 | |
paul@515 | 139 | /* A memory area containing other areas. */ |
paul@515 | 140 | |
paul@515 | 141 | class AvailableMemoryArea : public MemoryArea |
paul@515 | 142 | { |
paul@515 | 143 | protected: |
paul@515 | 144 | MemoryAreaMap _areas; |
paul@515 | 145 | MemoryAreas _allocated; |
paul@515 | 146 | |
paul@515 | 147 | public: |
paul@515 | 148 | explicit AvailableMemoryArea(address_t start, address_t end) |
paul@515 | 149 | : MemoryArea(start, end) |
paul@515 | 150 | { |
paul@515 | 151 | } |
paul@515 | 152 | |
paul@515 | 153 | virtual ~AvailableMemoryArea(); |
paul@515 | 154 | |
paul@515 | 155 | virtual MemoryArea *copy(); |
paul@515 | 156 | |
paul@515 | 157 | /* Support for populating areas. */ |
paul@515 | 158 | |
paul@515 | 159 | virtual long add(MemoryArea &area); |
paul@515 | 160 | |
paul@515 | 161 | virtual long remove(MemoryArea &area); |
paul@515 | 162 | |
paul@515 | 163 | /* Support for finding areas. */ |
paul@515 | 164 | |
paul@545 | 165 | virtual long find(address_t addr, MemoryArea **area, MemoryArea **parent); |
paul@515 | 166 | |
paul@515 | 167 | virtual long find(address_t *start, address_t *size, map_flags_t flags, |
paul@515 | 168 | unsigned char align, MemoryArea **area); |
paul@515 | 169 | |
paul@515 | 170 | /* A recursive iterator over a memory area. */ |
paul@515 | 171 | |
paul@515 | 172 | class iterator |
paul@515 | 173 | { |
paul@515 | 174 | protected: |
paul@515 | 175 | std::stack<MemoryAreaMap::iterator> _iterators, _ends; |
paul@515 | 176 | |
paul@515 | 177 | void ascend(); |
paul@515 | 178 | |
paul@515 | 179 | void descend(); |
paul@515 | 180 | |
paul@515 | 181 | void descend_all(); |
paul@515 | 182 | |
paul@515 | 183 | public: |
paul@515 | 184 | explicit iterator(); |
paul@515 | 185 | |
paul@515 | 186 | explicit iterator(MemoryAreaMap::iterator it, |
paul@515 | 187 | MemoryAreaMap::iterator end); |
paul@515 | 188 | |
paul@515 | 189 | MemoryArea *operator *(); |
paul@515 | 190 | |
paul@515 | 191 | iterator &operator ++(); |
paul@515 | 192 | |
paul@515 | 193 | iterator &operator ++(int); |
paul@515 | 194 | |
paul@515 | 195 | bool operator ==(iterator other); |
paul@515 | 196 | |
paul@515 | 197 | bool operator !=(iterator other); |
paul@515 | 198 | |
paul@515 | 199 | /* Access to the underlying iterators. */ |
paul@515 | 200 | |
paul@515 | 201 | MemoryAreaMap::iterator &area_iterator(); |
paul@515 | 202 | |
paul@515 | 203 | MemoryAreaMap::iterator &area_end(); |
paul@515 | 204 | }; |
paul@515 | 205 | |
paul@515 | 206 | /* Iteration methods. */ |
paul@515 | 207 | |
paul@515 | 208 | virtual iterator begin(); |
paul@515 | 209 | |
paul@515 | 210 | virtual iterator end(); |
paul@515 | 211 | |
paul@515 | 212 | virtual MemoryAreaMap::iterator areas_begin(); |
paul@515 | 213 | |
paul@515 | 214 | virtual MemoryAreaMap::iterator areas_end(); |
paul@515 | 215 | }; |
paul@515 | 216 | |
paul@515 | 217 | /* vim: tabstop=2 expandtab shiftwidth=2 |
paul@515 | 218 | */ |