diff options
Diffstat (limited to 'src/common/page_table.h')
| -rw-r--r-- | src/common/page_table.h | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/common/page_table.h b/src/common/page_table.h new file mode 100644 index 000000000..8339f2890 --- /dev/null +++ b/src/common/page_table.h | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <vector> | ||
| 8 | #include <boost/icl/interval_map.hpp> | ||
| 9 | #include "common/common_types.h" | ||
| 10 | #include "common/memory_hook.h" | ||
| 11 | |||
| 12 | namespace Common { | ||
| 13 | |||
| 14 | enum class PageType : u8 { | ||
| 15 | /// Page is unmapped and should cause an access error. | ||
| 16 | Unmapped, | ||
| 17 | /// Page is mapped to regular memory. This is the only type you can get pointers to. | ||
| 18 | Memory, | ||
| 19 | /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and | ||
| 20 | /// invalidation | ||
| 21 | RasterizerCachedMemory, | ||
| 22 | /// Page is mapped to a I/O region. Writing and reading to this page is handled by functions. | ||
| 23 | Special, | ||
| 24 | }; | ||
| 25 | |||
| 26 | struct SpecialRegion { | ||
| 27 | enum class Type { | ||
| 28 | DebugHook, | ||
| 29 | IODevice, | ||
| 30 | } type; | ||
| 31 | |||
| 32 | MemoryHookPointer handler; | ||
| 33 | |||
| 34 | bool operator<(const SpecialRegion& other) const { | ||
| 35 | return std::tie(type, handler) < std::tie(other.type, other.handler); | ||
| 36 | } | ||
| 37 | |||
| 38 | bool operator==(const SpecialRegion& other) const { | ||
| 39 | return std::tie(type, handler) == std::tie(other.type, other.handler); | ||
| 40 | } | ||
| 41 | }; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * A (reasonably) fast way of allowing switchable and remappable process address spaces. It loosely | ||
| 45 | * mimics the way a real CPU page table works. | ||
| 46 | */ | ||
| 47 | struct PageTable { | ||
| 48 | explicit PageTable(std::size_t page_size_in_bits); | ||
| 49 | ~PageTable(); | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Resizes the page table to be able to accomodate enough pages within | ||
| 53 | * a given address space. | ||
| 54 | * | ||
| 55 | * @param address_space_width_in_bits The address size width in bits. | ||
| 56 | */ | ||
| 57 | void Resize(std::size_t address_space_width_in_bits); | ||
| 58 | |||
| 59 | /** | ||
| 60 | * Vector of memory pointers backing each page. An entry can only be non-null if the | ||
| 61 | * corresponding entry in the `attributes` vector is of type `Memory`. | ||
| 62 | */ | ||
| 63 | std::vector<u8*> pointers; | ||
| 64 | |||
| 65 | /** | ||
| 66 | * Contains MMIO handlers that back memory regions whose entries in the `attribute` vector is | ||
| 67 | * of type `Special`. | ||
| 68 | */ | ||
| 69 | boost::icl::interval_map<VAddr, std::set<SpecialRegion>> special_regions; | ||
| 70 | |||
| 71 | /** | ||
| 72 | * Vector of fine grained page attributes. If it is set to any value other than `Memory`, then | ||
| 73 | * the corresponding entry in `pointers` MUST be set to null. | ||
| 74 | */ | ||
| 75 | std::vector<PageType> attributes; | ||
| 76 | |||
| 77 | const std::size_t page_size_in_bits{}; | ||
| 78 | }; | ||
| 79 | |||
| 80 | } // namespace Common | ||