summaryrefslogtreecommitdiff
path: root/src/core/memory.h
diff options
context:
space:
mode:
authorGravatar bunnei2019-11-28 11:43:17 -0500
committerGravatar GitHub2019-11-28 11:43:17 -0500
commite3ee017e91ef4d713f1af8cb60c5157e40d43f18 (patch)
treee0a5b47cac1d548599b8ceba7f71b40746fe6b48 /src/core/memory.h
parentMerge pull request #3171 from lioncash/internal-link (diff)
parentcore/memory; Migrate over SetCurrentPageTable() to the Memory class (diff)
downloadyuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.tar.gz
yuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.tar.xz
yuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.zip
Merge pull request #3169 from lioncash/memory
core/memory: Deglobalize memory management code
Diffstat (limited to 'src/core/memory.h')
-rw-r--r--src/core/memory.h396
1 files changed, 367 insertions, 29 deletions
diff --git a/src/core/memory.h b/src/core/memory.h
index 09008e1dd..1428a6d60 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -5,8 +5,18 @@
5#pragma once 5#pragma once
6 6
7#include <cstddef> 7#include <cstddef>
8#include <memory>
8#include <string> 9#include <string>
9#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/memory_hook.h"
12
13namespace Common {
14struct PageTable;
15}
16
17namespace Core {
18class System;
19}
10 20
11namespace Kernel { 21namespace Kernel {
12class Process; 22class Process;
@@ -36,41 +46,369 @@ enum : VAddr {
36 KERNEL_REGION_END = KERNEL_REGION_VADDR + KERNEL_REGION_SIZE, 46 KERNEL_REGION_END = KERNEL_REGION_VADDR + KERNEL_REGION_SIZE,
37}; 47};
38 48
39/// Changes the currently active page table to that of 49/// Central class that handles all memory operations and state.
40/// the given process instance. 50class Memory {
41void SetCurrentPageTable(Kernel::Process& process); 51public:
52 explicit Memory(Core::System& system);
53 ~Memory();
42 54
43/// Determines if the given VAddr is valid for the specified process. 55 Memory(const Memory&) = delete;
44bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr); 56 Memory& operator=(const Memory&) = delete;
45bool IsValidVirtualAddress(VAddr vaddr);
46/// Determines if the given VAddr is a kernel address
47bool IsKernelVirtualAddress(VAddr vaddr);
48 57
49u8 Read8(VAddr addr); 58 Memory(Memory&&) = default;
50u16 Read16(VAddr addr); 59 Memory& operator=(Memory&&) = default;
51u32 Read32(VAddr addr);
52u64 Read64(VAddr addr);
53 60
54void Write8(VAddr addr, u8 data); 61 /**
55void Write16(VAddr addr, u16 data); 62 * Changes the currently active page table to that of the given process instance.
56void Write32(VAddr addr, u32 data); 63 *
57void Write64(VAddr addr, u64 data); 64 * @param process The process to use the page table of.
65 */
66 void SetCurrentPageTable(Kernel::Process& process);
58 67
59void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, std::size_t size); 68 /**
60void ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size); 69 * Maps an allocated buffer onto a region of the emulated process address space.
61void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, 70 *
62 std::size_t size); 71 * @param page_table The page table of the emulated process.
63void WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size); 72 * @param base The address to start mapping at. Must be page-aligned.
64void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size); 73 * @param size The amount of bytes to map. Must be page-aligned.
65void CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size); 74 * @param target Buffer with the memory backing the mapping. Must be of length at least
75 * `size`.
76 */
77 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, u8* target);
66 78
67u8* GetPointer(VAddr vaddr); 79 /**
80 * Maps a region of the emulated process address space as a IO region.
81 *
82 * @param page_table The page table of the emulated process.
83 * @param base The address to start mapping at. Must be page-aligned.
84 * @param size The amount of bytes to map. Must be page-aligned.
85 * @param mmio_handler The handler that backs the mapping.
86 */
87 void MapIoRegion(Common::PageTable& page_table, VAddr base, u64 size,
88 Common::MemoryHookPointer mmio_handler);
68 89
69std::string ReadCString(VAddr vaddr, std::size_t max_length); 90 /**
91 * Unmaps a region of the emulated process address space.
92 *
93 * @param page_table The page table of the emulated process.
94 * @param base The address to begin unmapping at.
95 * @param size The amount of bytes to unmap.
96 */
97 void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size);
70 98
71/** 99 /**
72 * Mark each page touching the region as cached. 100 * Adds a memory hook to intercept reads and writes to given region of memory.
73 */ 101 *
74void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached); 102 * @param page_table The page table of the emulated process
103 * @param base The starting address to apply the hook to.
104 * @param size The size of the memory region to apply the hook to, in bytes.
105 * @param hook The hook to apply to the region of memory.
106 */
107 void AddDebugHook(Common::PageTable& page_table, VAddr base, u64 size,
108 Common::MemoryHookPointer hook);
109
110 /**
111 * Removes a memory hook from a given range of memory.
112 *
113 * @param page_table The page table of the emulated process.
114 * @param base The starting address to remove the hook from.
115 * @param size The size of the memory region to remove the hook from, in bytes.
116 * @param hook The hook to remove from the specified region of memory.
117 */
118 void RemoveDebugHook(Common::PageTable& page_table, VAddr base, u64 size,
119 Common::MemoryHookPointer hook);
120
121 /**
122 * Checks whether or not the supplied address is a valid virtual
123 * address for the given process.
124 *
125 * @param process The emulated process to check the address against.
126 * @param vaddr The virtual address to check the validity of.
127 *
128 * @returns True if the given virtual address is valid, false otherwise.
129 */
130 bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr) const;
131
132 /**
133 * Checks whether or not the supplied address is a valid virtual
134 * address for the current process.
135 *
136 * @param vaddr The virtual address to check the validity of.
137 *
138 * @returns True if the given virtual address is valid, false otherwise.
139 */
140 bool IsValidVirtualAddress(VAddr vaddr) const;
141
142 /**
143 * Gets a pointer to the given address.
144 *
145 * @param vaddr Virtual address to retrieve a pointer to.
146 *
147 * @returns The pointer to the given address, if the address is valid.
148 * If the address is not valid, nullptr will be returned.
149 */
150 u8* GetPointer(VAddr vaddr);
151
152 /**
153 * Gets a pointer to the given address.
154 *
155 * @param vaddr Virtual address to retrieve a pointer to.
156 *
157 * @returns The pointer to the given address, if the address is valid.
158 * If the address is not valid, nullptr will be returned.
159 */
160 const u8* GetPointer(VAddr vaddr) const;
161
162 /**
163 * Reads an 8-bit unsigned value from the current process' address space
164 * at the given virtual address.
165 *
166 * @param addr The virtual address to read the 8-bit value from.
167 *
168 * @returns the read 8-bit unsigned value.
169 */
170 u8 Read8(VAddr addr);
171
172 /**
173 * Reads a 16-bit unsigned value from the current process' address space
174 * at the given virtual address.
175 *
176 * @param addr The virtual address to read the 16-bit value from.
177 *
178 * @returns the read 16-bit unsigned value.
179 */
180 u16 Read16(VAddr addr);
181
182 /**
183 * Reads a 32-bit unsigned value from the current process' address space
184 * at the given virtual address.
185 *
186 * @param addr The virtual address to read the 32-bit value from.
187 *
188 * @returns the read 32-bit unsigned value.
189 */
190 u32 Read32(VAddr addr);
191
192 /**
193 * Reads a 64-bit unsigned value from the current process' address space
194 * at the given virtual address.
195 *
196 * @param addr The virtual address to read the 64-bit value from.
197 *
198 * @returns the read 64-bit value.
199 */
200 u64 Read64(VAddr addr);
201
202 /**
203 * Writes an 8-bit unsigned integer to the given virtual address in
204 * the current process' address space.
205 *
206 * @param addr The virtual address to write the 8-bit unsigned integer to.
207 * @param data The 8-bit unsigned integer to write to the given virtual address.
208 *
209 * @post The memory at the given virtual address contains the specified data value.
210 */
211 void Write8(VAddr addr, u8 data);
212
213 /**
214 * Writes a 16-bit unsigned integer to the given virtual address in
215 * the current process' address space.
216 *
217 * @param addr The virtual address to write the 16-bit unsigned integer to.
218 * @param data The 16-bit unsigned integer to write to the given virtual address.
219 *
220 * @post The memory range [addr, sizeof(data)) contains the given data value.
221 */
222 void Write16(VAddr addr, u16 data);
223
224 /**
225 * Writes a 32-bit unsigned integer to the given virtual address in
226 * the current process' address space.
227 *
228 * @param addr The virtual address to write the 32-bit unsigned integer to.
229 * @param data The 32-bit unsigned integer to write to the given virtual address.
230 *
231 * @post The memory range [addr, sizeof(data)) contains the given data value.
232 */
233 void Write32(VAddr addr, u32 data);
234
235 /**
236 * Writes a 64-bit unsigned integer to the given virtual address in
237 * the current process' address space.
238 *
239 * @param addr The virtual address to write the 64-bit unsigned integer to.
240 * @param data The 64-bit unsigned integer to write to the given virtual address.
241 *
242 * @post The memory range [addr, sizeof(data)) contains the given data value.
243 */
244 void Write64(VAddr addr, u64 data);
245
246 /**
247 * Reads a null-terminated string from the given virtual address.
248 * This function will continually read characters until either:
249 *
250 * - A null character ('\0') is reached.
251 * - max_length characters have been read.
252 *
253 * @note The final null-terminating character (if found) is not included
254 * in the returned string.
255 *
256 * @param vaddr The address to begin reading the string from.
257 * @param max_length The maximum length of the string to read in characters.
258 *
259 * @returns The read string.
260 */
261 std::string ReadCString(VAddr vaddr, std::size_t max_length);
262
263 /**
264 * Reads a contiguous block of bytes from a specified process' address space.
265 *
266 * @param process The process to read the data from.
267 * @param src_addr The virtual address to begin reading from.
268 * @param dest_buffer The buffer to place the read bytes into.
269 * @param size The amount of data to read, in bytes.
270 *
271 * @note If a size of 0 is specified, then this function reads nothing and
272 * no attempts to access memory are made at all.
273 *
274 * @pre dest_buffer must be at least size bytes in length, otherwise a
275 * buffer overrun will occur.
276 *
277 * @post The range [dest_buffer, size) contains the read bytes from the
278 * process' address space.
279 */
280 void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer,
281 std::size_t size);
282
283 /**
284 * Reads a contiguous block of bytes from the current process' address space.
285 *
286 * @param src_addr The virtual address to begin reading from.
287 * @param dest_buffer The buffer to place the read bytes into.
288 * @param size The amount of data to read, in bytes.
289 *
290 * @note If a size of 0 is specified, then this function reads nothing and
291 * no attempts to access memory are made at all.
292 *
293 * @pre dest_buffer must be at least size bytes in length, otherwise a
294 * buffer overrun will occur.
295 *
296 * @post The range [dest_buffer, size) contains the read bytes from the
297 * current process' address space.
298 */
299 void ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size);
300
301 /**
302 * Writes a range of bytes into a given process' address space at the specified
303 * virtual address.
304 *
305 * @param process The process to write data into the address space of.
306 * @param dest_addr The destination virtual address to begin writing the data at.
307 * @param src_buffer The data to write into the process' address space.
308 * @param size The size of the data to write, in bytes.
309 *
310 * @post The address range [dest_addr, size) in the process' address space
311 * contains the data that was within src_buffer.
312 *
313 * @post If an attempt is made to write into an unmapped region of memory, the writes
314 * will be ignored and an error will be logged.
315 *
316 * @post If a write is performed into a region of memory that is considered cached
317 * rasterizer memory, will cause the currently active rasterizer to be notified
318 * and will mark that region as invalidated to caches that the active
319 * graphics backend may be maintaining over the course of execution.
320 */
321 void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer,
322 std::size_t size);
323
324 /**
325 * Writes a range of bytes into the current process' address space at the specified
326 * virtual address.
327 *
328 * @param dest_addr The destination virtual address to begin writing the data at.
329 * @param src_buffer The data to write into the current process' address space.
330 * @param size The size of the data to write, in bytes.
331 *
332 * @post The address range [dest_addr, size) in the current process' address space
333 * contains the data that was within src_buffer.
334 *
335 * @post If an attempt is made to write into an unmapped region of memory, the writes
336 * will be ignored and an error will be logged.
337 *
338 * @post If a write is performed into a region of memory that is considered cached
339 * rasterizer memory, will cause the currently active rasterizer to be notified
340 * and will mark that region as invalidated to caches that the active
341 * graphics backend may be maintaining over the course of execution.
342 */
343 void WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size);
344
345 /**
346 * Fills the specified address range within a process' address space with zeroes.
347 *
348 * @param process The process that will have a portion of its memory zeroed out.
349 * @param dest_addr The starting virtual address of the range to zero out.
350 * @param size The size of the address range to zero out, in bytes.
351 *
352 * @post The range [dest_addr, size) within the process' address space is
353 * filled with zeroes.
354 */
355 void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size);
356
357 /**
358 * Fills the specified address range within the current process' address space with zeroes.
359 *
360 * @param dest_addr The starting virtual address of the range to zero out.
361 * @param size The size of the address range to zero out, in bytes.
362 *
363 * @post The range [dest_addr, size) within the current process' address space is
364 * filled with zeroes.
365 */
366 void ZeroBlock(VAddr dest_addr, std::size_t size);
367
368 /**
369 * Copies data within a process' address space to another location within the
370 * same address space.
371 *
372 * @param process The process that will have data copied within its address space.
373 * @param dest_addr The destination virtual address to begin copying the data into.
374 * @param src_addr The source virtual address to begin copying the data from.
375 * @param size The size of the data to copy, in bytes.
376 *
377 * @post The range [dest_addr, size) within the process' address space contains the
378 * same data within the range [src_addr, size).
379 */
380 void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
381 std::size_t size);
382
383 /**
384 * Copies data within the current process' address space to another location within the
385 * same address space.
386 *
387 * @param dest_addr The destination virtual address to begin copying the data into.
388 * @param src_addr The source virtual address to begin copying the data from.
389 * @param size The size of the data to copy, in bytes.
390 *
391 * @post The range [dest_addr, size) within the current process' address space
392 * contains the same data within the range [src_addr, size).
393 */
394 void CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size);
395
396 /**
397 * Marks each page within the specified address range as cached or uncached.
398 *
399 * @param vaddr The virtual address indicating the start of the address range.
400 * @param size The size of the address range in bytes.
401 * @param cached Whether or not any pages within the address range should be
402 * marked as cached or uncached.
403 */
404 void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached);
405
406private:
407 struct Impl;
408 std::unique_ptr<Impl> impl;
409};
410
411/// Determines if the given VAddr is a kernel address
412bool IsKernelVirtualAddress(VAddr vaddr);
75 413
76} // namespace Memory 414} // namespace Memory