diff options
| author | 2017-10-09 23:56:20 -0400 | |
|---|---|---|
| committer | 2017-10-09 23:56:20 -0400 | |
| commit | b1d5db1cf60344b6b081c9d03cb6ccc3264326cd (patch) | |
| tree | fde377c4ba3c0f92c032e6f5ec8627aae37270ef /src/core/memory.h | |
| parent | loader: Various improvements for NSO/NRO loaders. (diff) | |
| parent | Merge pull request #2996 from MerryMage/split-travis (diff) | |
| download | yuzu-b1d5db1cf60344b6b081c9d03cb6ccc3264326cd.tar.gz yuzu-b1d5db1cf60344b6b081c9d03cb6ccc3264326cd.tar.xz yuzu-b1d5db1cf60344b6b081c9d03cb6ccc3264326cd.zip | |
Merge remote-tracking branch 'upstream/master' into nx
# Conflicts:
# src/core/CMakeLists.txt
# src/core/arm/dynarmic/arm_dynarmic.cpp
# src/core/arm/dyncom/arm_dyncom.cpp
# src/core/hle/kernel/process.cpp
# src/core/hle/kernel/thread.cpp
# src/core/hle/kernel/thread.h
# src/core/hle/kernel/vm_manager.cpp
# src/core/loader/3dsx.cpp
# src/core/loader/elf.cpp
# src/core/loader/ncch.cpp
# src/core/memory.cpp
# src/core/memory.h
# src/core/memory_setup.h
Diffstat (limited to 'src/core/memory.h')
| -rw-r--r-- | src/core/memory.h | 91 |
1 files changed, 77 insertions, 14 deletions
diff --git a/src/core/memory.h b/src/core/memory.h index e14d68654..9a04b9a16 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -6,9 +6,16 @@ | |||
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <cstddef> | 8 | #include <cstddef> |
| 9 | #include <map> | ||
| 9 | #include <string> | 10 | #include <string> |
| 11 | #include <vector> | ||
| 10 | #include <boost/optional.hpp> | 12 | #include <boost/optional.hpp> |
| 11 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "core/mmio.h" | ||
| 15 | |||
| 16 | namespace Kernel { | ||
| 17 | class Process; | ||
| 18 | } | ||
| 12 | 19 | ||
| 13 | namespace Memory { | 20 | namespace Memory { |
| 14 | 21 | ||
| @@ -19,7 +26,60 @@ namespace Memory { | |||
| 19 | const int PAGE_BITS = 12; | 26 | const int PAGE_BITS = 12; |
| 20 | const u64 PAGE_SIZE = 1 << PAGE_BITS; | 27 | const u64 PAGE_SIZE = 1 << PAGE_BITS; |
| 21 | const u64 PAGE_MASK = PAGE_SIZE - 1; | 28 | const u64 PAGE_MASK = PAGE_SIZE - 1; |
| 22 | const size_t PAGE_TABLE_NUM_ENTRIES = 1ULL << (64 - PAGE_BITS); | 29 | const size_t PAGE_TABLE_NUM_ENTRIES = 1ULL << (32 - PAGE_BITS); |
| 30 | |||
| 31 | enum class PageType { | ||
| 32 | /// Page is unmapped and should cause an access error. | ||
| 33 | Unmapped, | ||
| 34 | /// Page is mapped to regular memory. This is the only type you can get pointers to. | ||
| 35 | Memory, | ||
| 36 | /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and | ||
| 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, | ||
| 41 | /// Page is mapped to a I/O region, but also needs to check for rasterizer cache flushing and | ||
| 42 | /// invalidation | ||
| 43 | RasterizerCachedSpecial, | ||
| 44 | }; | ||
| 45 | |||
| 46 | struct SpecialRegion { | ||
| 47 | VAddr base; | ||
| 48 | u32 size; | ||
| 49 | MMIORegionPointer handler; | ||
| 50 | }; | ||
| 51 | |||
| 52 | /** | ||
| 53 | * 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 | ||
| 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 | */ | ||
| 58 | struct PageTable { | ||
| 59 | /** | ||
| 60 | * Array of memory pointers backing each page. An entry can only be non-null if the | ||
| 61 | * corresponding entry in the `attributes` array is of type `Memory`. | ||
| 62 | */ | ||
| 63 | std::array<u8*, PAGE_TABLE_NUM_ENTRIES> pointers; | ||
| 64 | |||
| 65 | /** | ||
| 66 | * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of | ||
| 67 | * type `Special`. | ||
| 68 | */ | ||
| 69 | std::vector<SpecialRegion> special_regions; | ||
| 70 | |||
| 71 | /** | ||
| 72 | * 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. | ||
| 74 | */ | ||
| 75 | 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 | }; | ||
| 23 | 83 | ||
| 24 | /// Physical memory regions as seen from the ARM11 | 84 | /// Physical memory regions as seen from the ARM11 |
| 25 | enum : PAddr { | 85 | enum : PAddr { |
| @@ -126,7 +186,14 @@ enum : VAddr { | |||
| 126 | NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE, | 186 | NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE, |
| 127 | }; | 187 | }; |
| 128 | 188 | ||
| 189 | /// Currently active page table | ||
| 190 | void SetCurrentPageTable(PageTable* page_table); | ||
| 191 | PageTable* GetCurrentPageTable(); | ||
| 192 | |||
| 193 | /// Determines if the given VAddr is valid for the specified process. | ||
| 194 | bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr); | ||
| 129 | bool IsValidVirtualAddress(const VAddr addr); | 195 | bool IsValidVirtualAddress(const VAddr addr); |
| 196 | |||
| 130 | bool IsValidPhysicalAddress(const PAddr addr); | 197 | bool IsValidPhysicalAddress(const PAddr addr); |
| 131 | 198 | ||
| 132 | u8 Read8(VAddr addr); | 199 | u8 Read8(VAddr addr); |
| @@ -139,7 +206,11 @@ void Write16(VAddr addr, u16 data); | |||
| 139 | void Write32(VAddr addr, u32 data); | 206 | void Write32(VAddr addr, u32 data); |
| 140 | void Write64(VAddr addr, u64 data); | 207 | void Write64(VAddr addr, u64 data); |
| 141 | 208 | ||
| 209 | void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, | ||
| 210 | size_t size); | ||
| 142 | void ReadBlock(const VAddr src_addr, void* dest_buffer, size_t size); | 211 | void ReadBlock(const VAddr src_addr, void* dest_buffer, size_t size); |
| 212 | void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer, | ||
| 213 | size_t size); | ||
| 143 | void WriteBlock(const VAddr dest_addr, const void* src_buffer, size_t size); | 214 | void WriteBlock(const VAddr dest_addr, const void* src_buffer, size_t size); |
| 144 | void ZeroBlock(const VAddr dest_addr, const size_t size); | 215 | void ZeroBlock(const VAddr dest_addr, const size_t size); |
| 145 | void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size); | 216 | void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size); |
| @@ -169,8 +240,6 @@ boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr); | |||
| 169 | 240 | ||
| 170 | /** | 241 | /** |
| 171 | * Gets a pointer to the memory region beginning at the specified physical address. | 242 | * Gets a pointer to the memory region beginning at the specified physical address. |
| 172 | * | ||
| 173 | * @note This is currently implemented using PhysicalToVirtualAddress(). | ||
| 174 | */ | 243 | */ |
| 175 | u8* GetPhysicalPointer(PAddr address); | 244 | u8* GetPhysicalPointer(PAddr address); |
| 176 | 245 | ||
| @@ -178,17 +247,17 @@ u8* GetPhysicalPointer(PAddr address); | |||
| 178 | * Adds the supplied value to the rasterizer resource cache counter of each | 247 | * Adds the supplied value to the rasterizer resource cache counter of each |
| 179 | * page touching the region. | 248 | * page touching the region. |
| 180 | */ | 249 | */ |
| 181 | void RasterizerMarkRegionCached(PAddr start, u64 size, int count_delta); | 250 | void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta); |
| 182 | 251 | ||
| 183 | /** | 252 | /** |
| 184 | * Flushes any externally cached rasterizer resources touching the given region. | 253 | * Flushes any externally cached rasterizer resources touching the given region. |
| 185 | */ | 254 | */ |
| 186 | void RasterizerFlushRegion(PAddr start, u64 size); | 255 | void RasterizerFlushRegion(PAddr start, u32 size); |
| 187 | 256 | ||
| 188 | /** | 257 | /** |
| 189 | * Flushes and invalidates any externally cached rasterizer resources touching the given region. | 258 | * Flushes and invalidates any externally cached rasterizer resources touching the given region. |
| 190 | */ | 259 | */ |
| 191 | void RasterizerFlushAndInvalidateRegion(PAddr start, u64 size); | 260 | void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size); |
| 192 | 261 | ||
| 193 | enum class FlushMode { | 262 | enum class FlushMode { |
| 194 | /// Write back modified surfaces to RAM | 263 | /// Write back modified surfaces to RAM |
| @@ -201,12 +270,6 @@ enum class FlushMode { | |||
| 201 | * Flushes and invalidates any externally cached rasterizer resources touching the given virtual | 270 | * Flushes and invalidates any externally cached rasterizer resources touching the given virtual |
| 202 | * address region. | 271 | * address region. |
| 203 | */ | 272 | */ |
| 204 | void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode); | 273 | void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode); |
| 205 | 274 | ||
| 206 | /** | 275 | } // namespace Memory |
| 207 | * Dynarmic has an optimization to memory accesses when the pointer to the page exists that | ||
| 208 | * can be used by setting up the current page table as a callback. This function is used to | ||
| 209 | * retrieve the current page table for that purpose. | ||
| 210 | */ | ||
| 211 | //std::array<u8*, PAGE_TABLE_NUM_ENTRIES>* GetCurrentPageTablePointers(); | ||
| 212 | } | ||