diff options
| author | 2017-09-15 22:41:45 +0200 | |
|---|---|---|
| committer | 2017-09-15 22:41:45 +0200 | |
| commit | 813837c5cf3e63a4ac08f4ec463bd2b2b87ab1c6 (patch) | |
| tree | df43bf978de3b699a22650d3ff2a3ebb5d86b2de /src/core/memory.h | |
| parent | Merge pull request #2915 from wwylele/font-archive-2 (diff) | |
| parent | CPU/Dynarmic: Disable the fast page-table access in dynarmic until it support... (diff) | |
| download | yuzu-813837c5cf3e63a4ac08f4ec463bd2b2b87ab1c6.tar.gz yuzu-813837c5cf3e63a4ac08f4ec463bd2b2b87ab1c6.tar.xz yuzu-813837c5cf3e63a4ac08f4ec463bd2b2b87ab1c6.zip | |
Merge pull request #2842 from Subv/switchable_page_table
Kernel/Memory: Give each process its own page table and allow switching the current page table upon reschedule
Diffstat (limited to 'src/core/memory.h')
| -rw-r--r-- | src/core/memory.h | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/src/core/memory.h b/src/core/memory.h index c8c56babd..b228a48c2 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -7,8 +7,10 @@ | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <cstddef> | 8 | #include <cstddef> |
| 9 | #include <string> | 9 | #include <string> |
| 10 | #include <vector> | ||
| 10 | #include <boost/optional.hpp> | 11 | #include <boost/optional.hpp> |
| 11 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 13 | #include "core/mmio.h" | ||
| 12 | 14 | ||
| 13 | namespace Memory { | 15 | namespace Memory { |
| 14 | 16 | ||
| @@ -21,6 +23,59 @@ const u32 PAGE_MASK = PAGE_SIZE - 1; | |||
| 21 | const int PAGE_BITS = 12; | 23 | const int PAGE_BITS = 12; |
| 22 | const size_t PAGE_TABLE_NUM_ENTRIES = 1 << (32 - PAGE_BITS); | 24 | const size_t PAGE_TABLE_NUM_ENTRIES = 1 << (32 - PAGE_BITS); |
| 23 | 25 | ||
| 26 | enum class PageType { | ||
| 27 | /// Page is unmapped and should cause an access error. | ||
| 28 | Unmapped, | ||
| 29 | /// Page is mapped to regular memory. This is the only type you can get pointers to. | ||
| 30 | Memory, | ||
| 31 | /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and | ||
| 32 | /// invalidation | ||
| 33 | RasterizerCachedMemory, | ||
| 34 | /// Page is mapped to a I/O region. Writing and reading to this page is handled by functions. | ||
| 35 | Special, | ||
| 36 | /// Page is mapped to a I/O region, but also needs to check for rasterizer cache flushing and | ||
| 37 | /// invalidation | ||
| 38 | RasterizerCachedSpecial, | ||
| 39 | }; | ||
| 40 | |||
| 41 | struct SpecialRegion { | ||
| 42 | VAddr base; | ||
| 43 | u32 size; | ||
| 44 | MMIORegionPointer handler; | ||
| 45 | }; | ||
| 46 | |||
| 47 | /** | ||
| 48 | * A (reasonably) fast way of allowing switchable and remappable process address spaces. It loosely | ||
| 49 | * mimics the way a real CPU page table works, but instead is optimized for minimal decoding and | ||
| 50 | * fetching requirements when accessing. In the usual case of an access to regular memory, it only | ||
| 51 | * requires an indexed fetch and a check for NULL. | ||
| 52 | */ | ||
| 53 | struct PageTable { | ||
| 54 | /** | ||
| 55 | * Array of memory pointers backing each page. An entry can only be non-null if the | ||
| 56 | * corresponding entry in the `attributes` array is of type `Memory`. | ||
| 57 | */ | ||
| 58 | std::array<u8*, PAGE_TABLE_NUM_ENTRIES> pointers; | ||
| 59 | |||
| 60 | /** | ||
| 61 | * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of | ||
| 62 | * type `Special`. | ||
| 63 | */ | ||
| 64 | std::vector<SpecialRegion> special_regions; | ||
| 65 | |||
| 66 | /** | ||
| 67 | * Array of fine grained page attributes. If it is set to any value other than `Memory`, then | ||
| 68 | * the corresponding entry in `pointers` MUST be set to null. | ||
| 69 | */ | ||
| 70 | std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; | ||
| 71 | |||
| 72 | /** | ||
| 73 | * Indicates the number of externally cached resources touching a page that should be | ||
| 74 | * flushed before the memory is accessed | ||
| 75 | */ | ||
| 76 | std::array<u8, PAGE_TABLE_NUM_ENTRIES> cached_res_count; | ||
| 77 | }; | ||
| 78 | |||
| 24 | /// Physical memory regions as seen from the ARM11 | 79 | /// Physical memory regions as seen from the ARM11 |
| 25 | enum : PAddr { | 80 | enum : PAddr { |
| 26 | /// IO register area | 81 | /// IO register area |
| @@ -126,6 +181,9 @@ enum : VAddr { | |||
| 126 | NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE, | 181 | NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE, |
| 127 | }; | 182 | }; |
| 128 | 183 | ||
| 184 | /// Currently active page table | ||
| 185 | extern PageTable* current_page_table; | ||
| 186 | |||
| 129 | bool IsValidVirtualAddress(const VAddr addr); | 187 | bool IsValidVirtualAddress(const VAddr addr); |
| 130 | bool IsValidPhysicalAddress(const PAddr addr); | 188 | bool IsValidPhysicalAddress(const PAddr addr); |
| 131 | 189 | ||
| @@ -169,8 +227,6 @@ boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr); | |||
| 169 | 227 | ||
| 170 | /** | 228 | /** |
| 171 | * Gets a pointer to the memory region beginning at the specified physical address. | 229 | * Gets a pointer to the memory region beginning at the specified physical address. |
| 172 | * | ||
| 173 | * @note This is currently implemented using PhysicalToVirtualAddress(). | ||
| 174 | */ | 230 | */ |
| 175 | u8* GetPhysicalPointer(PAddr address); | 231 | u8* GetPhysicalPointer(PAddr address); |
| 176 | 232 | ||
| @@ -209,4 +265,4 @@ void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode); | |||
| 209 | * retrieve the current page table for that purpose. | 265 | * retrieve the current page table for that purpose. |
| 210 | */ | 266 | */ |
| 211 | std::array<u8*, PAGE_TABLE_NUM_ENTRIES>* GetCurrentPageTablePointers(); | 267 | std::array<u8*, PAGE_TABLE_NUM_ENTRIES>* GetCurrentPageTablePointers(); |
| 212 | } | 268 | } // namespace Memory |