diff options
| author | 2018-01-27 15:16:39 +0000 | |
|---|---|---|
| committer | 2018-01-27 15:16:39 +0000 | |
| commit | 738f91a57da7c129d1ee85b7abbf6858f8669ee3 (patch) | |
| tree | 3ef164d8e79c0aea6ab72dc9b8fa78877a82338a /src/core/memory.h | |
| parent | externals: Update dynarmic (diff) | |
| download | yuzu-738f91a57da7c129d1ee85b7abbf6858f8669ee3.tar.gz yuzu-738f91a57da7c129d1ee85b7abbf6858f8669ee3.tar.xz yuzu-738f91a57da7c129d1ee85b7abbf6858f8669ee3.zip | |
memory: Replace all memory hooking with Special regions
Diffstat (limited to 'src/core/memory.h')
| -rw-r--r-- | src/core/memory.h | 72 |
1 files changed, 21 insertions, 51 deletions
diff --git a/src/core/memory.h b/src/core/memory.h index 7e554f394..b2158ca46 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -8,10 +8,12 @@ | |||
| 8 | #include <cstddef> | 8 | #include <cstddef> |
| 9 | #include <map> | 9 | #include <map> |
| 10 | #include <string> | 10 | #include <string> |
| 11 | #include <tuple> | ||
| 11 | #include <vector> | 12 | #include <vector> |
| 13 | #include <boost/icl/interval_map.hpp> | ||
| 12 | #include <boost/optional.hpp> | 14 | #include <boost/optional.hpp> |
| 13 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| 14 | #include "core/mmio.h" | 16 | #include "core/memory_hook.h" |
| 15 | 17 | ||
| 16 | namespace Kernel { | 18 | namespace Kernel { |
| 17 | class Process; | 19 | class Process; |
| @@ -28,32 +30,35 @@ const u64 PAGE_SIZE = 1 << PAGE_BITS; | |||
| 28 | const u64 PAGE_MASK = PAGE_SIZE - 1; | 30 | const u64 PAGE_MASK = PAGE_SIZE - 1; |
| 29 | const size_t PAGE_TABLE_NUM_ENTRIES = 1ULL << (36 - PAGE_BITS); | 31 | const size_t PAGE_TABLE_NUM_ENTRIES = 1ULL << (36 - PAGE_BITS); |
| 30 | 32 | ||
| 31 | enum class PageType { | 33 | enum class PageType : u8 { |
| 32 | /// Page is unmapped and should cause an access error. | 34 | /// Page is unmapped and should cause an access error. |
| 33 | Unmapped, | 35 | Unmapped, |
| 34 | /// Page is mapped to regular memory. This is the only type you can get pointers to. | 36 | /// Page is mapped to regular memory. This is the only type you can get pointers to. |
| 35 | Memory, | 37 | Memory, |
| 36 | /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and | 38 | /// Page is mapped to a memory hook, which intercepts read and write requests. |
| 37 | /// invalidation | ||
| 38 | RasterizerCachedMemory, | ||
| 39 | /// Page is mapped to a I/O region. Writing and reading to this page is handled by functions. | ||
| 40 | Special, | 39 | Special, |
| 41 | /// Page is mapped to a I/O region, but also needs to check for rasterizer cache flushing and | ||
| 42 | /// invalidation | ||
| 43 | RasterizerCachedSpecial, | ||
| 44 | }; | 40 | }; |
| 45 | 41 | ||
| 46 | struct SpecialRegion { | 42 | struct SpecialRegion { |
| 47 | VAddr base; | 43 | enum class Type { |
| 48 | u64 size; | 44 | DebugHook, |
| 49 | MMIORegionPointer handler; | 45 | IODevice, |
| 46 | } type; | ||
| 47 | |||
| 48 | MemoryHookPointer handler; | ||
| 49 | |||
| 50 | bool operator<(const SpecialRegion& other) const { | ||
| 51 | return std::tie(type, handler) < std::tie(other.type, other.handler); | ||
| 52 | } | ||
| 53 | |||
| 54 | bool operator==(const SpecialRegion& other) const { | ||
| 55 | return std::tie(type, handler) == std::tie(other.type, other.handler); | ||
| 56 | } | ||
| 50 | }; | 57 | }; |
| 51 | 58 | ||
| 52 | /** | 59 | /** |
| 53 | * A (reasonably) fast way of allowing switchable and remappable process address spaces. It loosely | 60 | * A (reasonably) fast way of allowing switchable and remappable process address spaces. It loosely |
| 54 | * mimics the way a real CPU page table works, but instead is optimized for minimal decoding and | 61 | * mimics the way a real CPU page table works. |
| 55 | * fetching requirements when accessing. In the usual case of an access to regular memory, it only | ||
| 56 | * requires an indexed fetch and a check for NULL. | ||
| 57 | */ | 62 | */ |
| 58 | struct PageTable { | 63 | struct PageTable { |
| 59 | /** | 64 | /** |
| @@ -66,19 +71,13 @@ struct PageTable { | |||
| 66 | * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of | 71 | * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of |
| 67 | * type `Special`. | 72 | * type `Special`. |
| 68 | */ | 73 | */ |
| 69 | std::vector<SpecialRegion> special_regions; | 74 | boost::icl::interval_map<VAddr, std::set<SpecialRegion>> special_regions; |
| 70 | 75 | ||
| 71 | /** | 76 | /** |
| 72 | * Array of fine grained page attributes. If it is set to any value other than `Memory`, then | 77 | * Array 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. | 78 | * the corresponding entry in `pointers` MUST be set to null. |
| 74 | */ | 79 | */ |
| 75 | std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; | 80 | std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; |
| 76 | |||
| 77 | /** | ||
| 78 | * Indicates the number of externally cached resources touching a page that should be | ||
| 79 | * flushed before the memory is accessed | ||
| 80 | */ | ||
| 81 | std::array<u8, PAGE_TABLE_NUM_ENTRIES> cached_res_count; | ||
| 82 | }; | 81 | }; |
| 83 | 82 | ||
| 84 | /// Physical memory regions as seen from the ARM11 | 83 | /// Physical memory regions as seen from the ARM11 |
| @@ -243,33 +242,4 @@ boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr); | |||
| 243 | */ | 242 | */ |
| 244 | u8* GetPhysicalPointer(PAddr address); | 243 | u8* GetPhysicalPointer(PAddr address); |
| 245 | 244 | ||
| 246 | /** | ||
| 247 | * Adds the supplied value to the rasterizer resource cache counter of each | ||
| 248 | * page touching the region. | ||
| 249 | */ | ||
| 250 | void RasterizerMarkRegionCached(PAddr start, u64 size, int count_delta); | ||
| 251 | |||
| 252 | /** | ||
| 253 | * Flushes any externally cached rasterizer resources touching the given region. | ||
| 254 | */ | ||
| 255 | void RasterizerFlushRegion(PAddr start, u64 size); | ||
| 256 | |||
| 257 | /** | ||
| 258 | * Flushes and invalidates any externally cached rasterizer resources touching the given region. | ||
| 259 | */ | ||
| 260 | void RasterizerFlushAndInvalidateRegion(PAddr start, u64 size); | ||
| 261 | |||
| 262 | enum class FlushMode { | ||
| 263 | /// Write back modified surfaces to RAM | ||
| 264 | Flush, | ||
| 265 | /// Write back modified surfaces to RAM, and also remove them from the cache | ||
| 266 | FlushAndInvalidate, | ||
| 267 | }; | ||
| 268 | |||
| 269 | /** | ||
| 270 | * Flushes and invalidates any externally cached rasterizer resources touching the given virtual | ||
| 271 | * address region. | ||
| 272 | */ | ||
| 273 | void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode); | ||
| 274 | |||
| 275 | } // namespace Memory | 245 | } // namespace Memory |