summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp201
1 files changed, 93 insertions, 108 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 6061d37ae..9d87045a0 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -14,13 +14,14 @@
14#include "common/swap.h" 14#include "common/swap.h"
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#include "core/core.h" 16#include "core/core.h"
17#include "core/device_memory.h"
18#include "core/hle/kernel/memory/page_table.h"
17#include "core/hle/kernel/physical_memory.h" 19#include "core/hle/kernel/physical_memory.h"
18#include "core/hle/kernel/process.h" 20#include "core/hle/kernel/process.h"
19#include "core/hle/kernel/vm_manager.h"
20#include "core/memory.h" 21#include "core/memory.h"
21#include "video_core/gpu.h" 22#include "video_core/gpu.h"
22 23
23namespace Memory { 24namespace Core::Memory {
24 25
25// Implementation class used to keep the specifics of the memory subsystem hidden 26// Implementation class used to keep the specifics of the memory subsystem hidden
26// from outside classes. This also allows modification to the internals of the memory 27// from outside classes. This also allows modification to the internals of the memory
@@ -29,9 +30,9 @@ struct Memory::Impl {
29 explicit Impl(Core::System& system_) : system{system_} {} 30 explicit Impl(Core::System& system_) : system{system_} {}
30 31
31 void SetCurrentPageTable(Kernel::Process& process) { 32 void SetCurrentPageTable(Kernel::Process& process) {
32 current_page_table = &process.VMManager().page_table; 33 current_page_table = &process.PageTable().PageTableImpl();
33 34
34 const std::size_t address_space_width = process.VMManager().GetAddressSpaceWidth(); 35 const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth();
35 36
36 system.ArmInterface(0).PageTableChanged(*current_page_table, address_space_width); 37 system.ArmInterface(0).PageTableChanged(*current_page_table, address_space_width);
37 system.ArmInterface(1).PageTableChanged(*current_page_table, address_space_width); 38 system.ArmInterface(1).PageTableChanged(*current_page_table, address_space_width);
@@ -39,12 +40,7 @@ struct Memory::Impl {
39 system.ArmInterface(3).PageTableChanged(*current_page_table, address_space_width); 40 system.ArmInterface(3).PageTableChanged(*current_page_table, address_space_width);
40 } 41 }
41 42
42 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, 43 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) {
43 Kernel::PhysicalMemory& memory, VAddr offset) {
44 MapMemoryRegion(page_table, base, size, memory.data() + offset);
45 }
46
47 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, u8* target) {
48 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size); 44 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
49 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base); 45 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
50 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory); 46 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
@@ -52,46 +48,27 @@ struct Memory::Impl {
52 48
53 void MapIoRegion(Common::PageTable& page_table, VAddr base, u64 size, 49 void MapIoRegion(Common::PageTable& page_table, VAddr base, u64 size,
54 Common::MemoryHookPointer mmio_handler) { 50 Common::MemoryHookPointer mmio_handler) {
55 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size); 51 UNIMPLEMENTED();
56 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
57 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, nullptr,
58 Common::PageType::Special);
59
60 const auto interval = boost::icl::discrete_interval<VAddr>::closed(base, base + size - 1);
61 const Common::SpecialRegion region{Common::SpecialRegion::Type::IODevice,
62 std::move(mmio_handler)};
63 page_table.special_regions.add(
64 std::make_pair(interval, std::set<Common::SpecialRegion>{region}));
65 } 52 }
66 53
67 void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) { 54 void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
68 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size); 55 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
69 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base); 56 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
70 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, nullptr, 57 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped);
71 Common::PageType::Unmapped);
72
73 const auto interval = boost::icl::discrete_interval<VAddr>::closed(base, base + size - 1);
74 page_table.special_regions.erase(interval);
75 } 58 }
76 59
77 void AddDebugHook(Common::PageTable& page_table, VAddr base, u64 size, 60 void AddDebugHook(Common::PageTable& page_table, VAddr base, u64 size,
78 Common::MemoryHookPointer hook) { 61 Common::MemoryHookPointer hook) {
79 const auto interval = boost::icl::discrete_interval<VAddr>::closed(base, base + size - 1); 62 UNIMPLEMENTED();
80 const Common::SpecialRegion region{Common::SpecialRegion::Type::DebugHook, std::move(hook)};
81 page_table.special_regions.add(
82 std::make_pair(interval, std::set<Common::SpecialRegion>{region}));
83 } 63 }
84 64
85 void RemoveDebugHook(Common::PageTable& page_table, VAddr base, u64 size, 65 void RemoveDebugHook(Common::PageTable& page_table, VAddr base, u64 size,
86 Common::MemoryHookPointer hook) { 66 Common::MemoryHookPointer hook) {
87 const auto interval = boost::icl::discrete_interval<VAddr>::closed(base, base + size - 1); 67 UNIMPLEMENTED();
88 const Common::SpecialRegion region{Common::SpecialRegion::Type::DebugHook, std::move(hook)};
89 page_table.special_regions.subtract(
90 std::make_pair(interval, std::set<Common::SpecialRegion>{region}));
91 } 68 }
92 69
93 bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const { 70 bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const {
94 const auto& page_table = process.VMManager().page_table; 71 const auto& page_table = process.PageTable().PageTableImpl();
95 72
96 const u8* const page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; 73 const u8* const page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
97 if (page_pointer != nullptr) { 74 if (page_pointer != nullptr) {
@@ -113,55 +90,28 @@ struct Memory::Impl {
113 return IsValidVirtualAddress(*system.CurrentProcess(), vaddr); 90 return IsValidVirtualAddress(*system.CurrentProcess(), vaddr);
114 } 91 }
115 92
116 /** 93 u8* GetPointerFromRasterizerCachedMemory(VAddr vaddr) const {
117 * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned) 94 const PAddr paddr{current_page_table->backing_addr[vaddr >> PAGE_BITS]};
118 * using a VMA from the current process
119 */
120 u8* GetPointerFromVMA(const Kernel::Process& process, VAddr vaddr) {
121 const auto& vm_manager = process.VMManager();
122 95
123 const auto it = vm_manager.FindVMA(vaddr); 96 if (!paddr) {
124 DEBUG_ASSERT(vm_manager.IsValidHandle(it)); 97 return {};
125
126 u8* direct_pointer = nullptr;
127 const auto& vma = it->second;
128 switch (vma.type) {
129 case Kernel::VMAType::AllocatedMemoryBlock:
130 direct_pointer = vma.backing_block->data() + vma.offset;
131 break;
132 case Kernel::VMAType::BackingMemory:
133 direct_pointer = vma.backing_memory;
134 break;
135 case Kernel::VMAType::Free:
136 return nullptr;
137 default:
138 UNREACHABLE();
139 } 98 }
140 99
141 return direct_pointer + (vaddr - vma.base); 100 return system.DeviceMemory().GetPointer(paddr) + vaddr;
142 } 101 }
143 102
144 /** 103 u8* GetPointer(const VAddr vaddr) const {
145 * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned) 104 u8* const page_pointer{current_page_table->pointers[vaddr >> PAGE_BITS]};
146 * using a VMA from the current process. 105 if (page_pointer) {
147 */
148 u8* GetPointerFromVMA(VAddr vaddr) {
149 return GetPointerFromVMA(*system.CurrentProcess(), vaddr);
150 }
151
152 u8* GetPointer(const VAddr vaddr) {
153 u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
154 if (page_pointer != nullptr) {
155 return page_pointer + vaddr; 106 return page_pointer + vaddr;
156 } 107 }
157 108
158 if (current_page_table->attributes[vaddr >> PAGE_BITS] == 109 if (current_page_table->attributes[vaddr >> PAGE_BITS] ==
159 Common::PageType::RasterizerCachedMemory) { 110 Common::PageType::RasterizerCachedMemory) {
160 return GetPointerFromVMA(vaddr); 111 return GetPointerFromRasterizerCachedMemory(vaddr);
161 } 112 }
162 113
163 LOG_ERROR(HW_Memory, "Unknown GetPointer @ 0x{:016X}", vaddr); 114 return {};
164 return nullptr;
165 } 115 }
166 116
167 u8 Read8(const VAddr addr) { 117 u8 Read8(const VAddr addr) {
@@ -169,15 +119,33 @@ struct Memory::Impl {
169 } 119 }
170 120
171 u16 Read16(const VAddr addr) { 121 u16 Read16(const VAddr addr) {
172 return Read<u16_le>(addr); 122 if ((addr & 1) == 0) {
123 return Read<u16_le>(addr);
124 } else {
125 const u8 a{Read<u8>(addr)};
126 const u8 b{Read<u8>(addr + sizeof(u8))};
127 return (static_cast<u16>(b) << 8) | a;
128 }
173 } 129 }
174 130
175 u32 Read32(const VAddr addr) { 131 u32 Read32(const VAddr addr) {
176 return Read<u32_le>(addr); 132 if ((addr & 3) == 0) {
133 return Read<u32_le>(addr);
134 } else {
135 const u16 a{Read16(addr)};
136 const u16 b{Read16(addr + sizeof(u16))};
137 return (static_cast<u32>(b) << 16) | a;
138 }
177 } 139 }
178 140
179 u64 Read64(const VAddr addr) { 141 u64 Read64(const VAddr addr) {
180 return Read<u64_le>(addr); 142 if ((addr & 7) == 0) {
143 return Read<u64_le>(addr);
144 } else {
145 const u32 a{Read32(addr)};
146 const u32 b{Read32(addr + sizeof(u32))};
147 return (static_cast<u64>(b) << 32) | a;
148 }
181 } 149 }
182 150
183 void Write8(const VAddr addr, const u8 data) { 151 void Write8(const VAddr addr, const u8 data) {
@@ -185,15 +153,30 @@ struct Memory::Impl {
185 } 153 }
186 154
187 void Write16(const VAddr addr, const u16 data) { 155 void Write16(const VAddr addr, const u16 data) {
188 Write<u16_le>(addr, data); 156 if ((addr & 1) == 0) {
157 Write<u16_le>(addr, data);
158 } else {
159 Write<u8>(addr, static_cast<u8>(data));
160 Write<u8>(addr + sizeof(u8), static_cast<u8>(data >> 8));
161 }
189 } 162 }
190 163
191 void Write32(const VAddr addr, const u32 data) { 164 void Write32(const VAddr addr, const u32 data) {
192 Write<u32_le>(addr, data); 165 if ((addr & 3) == 0) {
166 Write<u32_le>(addr, data);
167 } else {
168 Write16(addr, static_cast<u16>(data));
169 Write16(addr + sizeof(u16), static_cast<u16>(data >> 16));
170 }
193 } 171 }
194 172
195 void Write64(const VAddr addr, const u64 data) { 173 void Write64(const VAddr addr, const u64 data) {
196 Write<u64_le>(addr, data); 174 if ((addr & 7) == 0) {
175 Write<u64_le>(addr, data);
176 } else {
177 Write32(addr, static_cast<u32>(data));
178 Write32(addr + sizeof(u32), static_cast<u32>(data >> 32));
179 }
197 } 180 }
198 181
199 std::string ReadCString(VAddr vaddr, std::size_t max_length) { 182 std::string ReadCString(VAddr vaddr, std::size_t max_length) {
@@ -213,7 +196,7 @@ struct Memory::Impl {
213 196
214 void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, 197 void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
215 const std::size_t size) { 198 const std::size_t size) {
216 const auto& page_table = process.VMManager().page_table; 199 const auto& page_table = process.PageTable().PageTableImpl();
217 200
218 std::size_t remaining_size = size; 201 std::size_t remaining_size = size;
219 std::size_t page_index = src_addr >> PAGE_BITS; 202 std::size_t page_index = src_addr >> PAGE_BITS;
@@ -241,7 +224,7 @@ struct Memory::Impl {
241 break; 224 break;
242 } 225 }
243 case Common::PageType::RasterizerCachedMemory: { 226 case Common::PageType::RasterizerCachedMemory: {
244 const u8* const host_ptr = GetPointerFromVMA(process, current_vaddr); 227 const u8* const host_ptr{GetPointerFromRasterizerCachedMemory(current_vaddr)};
245 system.GPU().FlushRegion(current_vaddr, copy_amount); 228 system.GPU().FlushRegion(current_vaddr, copy_amount);
246 std::memcpy(dest_buffer, host_ptr, copy_amount); 229 std::memcpy(dest_buffer, host_ptr, copy_amount);
247 break; 230 break;
@@ -259,7 +242,7 @@ struct Memory::Impl {
259 242
260 void ReadBlockUnsafe(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, 243 void ReadBlockUnsafe(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
261 const std::size_t size) { 244 const std::size_t size) {
262 const auto& page_table = process.VMManager().page_table; 245 const auto& page_table = process.PageTable().PageTableImpl();
263 246
264 std::size_t remaining_size = size; 247 std::size_t remaining_size = size;
265 std::size_t page_index = src_addr >> PAGE_BITS; 248 std::size_t page_index = src_addr >> PAGE_BITS;
@@ -287,7 +270,7 @@ struct Memory::Impl {
287 break; 270 break;
288 } 271 }
289 case Common::PageType::RasterizerCachedMemory: { 272 case Common::PageType::RasterizerCachedMemory: {
290 const u8* const host_ptr = GetPointerFromVMA(process, current_vaddr); 273 const u8* const host_ptr{GetPointerFromRasterizerCachedMemory(current_vaddr)};
291 std::memcpy(dest_buffer, host_ptr, copy_amount); 274 std::memcpy(dest_buffer, host_ptr, copy_amount);
292 break; 275 break;
293 } 276 }
@@ -312,7 +295,7 @@ struct Memory::Impl {
312 295
313 void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer, 296 void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer,
314 const std::size_t size) { 297 const std::size_t size) {
315 const auto& page_table = process.VMManager().page_table; 298 const auto& page_table = process.PageTable().PageTableImpl();
316 std::size_t remaining_size = size; 299 std::size_t remaining_size = size;
317 std::size_t page_index = dest_addr >> PAGE_BITS; 300 std::size_t page_index = dest_addr >> PAGE_BITS;
318 std::size_t page_offset = dest_addr & PAGE_MASK; 301 std::size_t page_offset = dest_addr & PAGE_MASK;
@@ -338,7 +321,7 @@ struct Memory::Impl {
338 break; 321 break;
339 } 322 }
340 case Common::PageType::RasterizerCachedMemory: { 323 case Common::PageType::RasterizerCachedMemory: {
341 u8* const host_ptr = GetPointerFromVMA(process, current_vaddr); 324 u8* const host_ptr{GetPointerFromRasterizerCachedMemory(current_vaddr)};
342 system.GPU().InvalidateRegion(current_vaddr, copy_amount); 325 system.GPU().InvalidateRegion(current_vaddr, copy_amount);
343 std::memcpy(host_ptr, src_buffer, copy_amount); 326 std::memcpy(host_ptr, src_buffer, copy_amount);
344 break; 327 break;
@@ -356,7 +339,7 @@ struct Memory::Impl {
356 339
357 void WriteBlockUnsafe(const Kernel::Process& process, const VAddr dest_addr, 340 void WriteBlockUnsafe(const Kernel::Process& process, const VAddr dest_addr,
358 const void* src_buffer, const std::size_t size) { 341 const void* src_buffer, const std::size_t size) {
359 const auto& page_table = process.VMManager().page_table; 342 const auto& page_table = process.PageTable().PageTableImpl();
360 std::size_t remaining_size = size; 343 std::size_t remaining_size = size;
361 std::size_t page_index = dest_addr >> PAGE_BITS; 344 std::size_t page_index = dest_addr >> PAGE_BITS;
362 std::size_t page_offset = dest_addr & PAGE_MASK; 345 std::size_t page_offset = dest_addr & PAGE_MASK;
@@ -382,7 +365,7 @@ struct Memory::Impl {
382 break; 365 break;
383 } 366 }
384 case Common::PageType::RasterizerCachedMemory: { 367 case Common::PageType::RasterizerCachedMemory: {
385 u8* const host_ptr = GetPointerFromVMA(process, current_vaddr); 368 u8* const host_ptr{GetPointerFromRasterizerCachedMemory(current_vaddr)};
386 std::memcpy(host_ptr, src_buffer, copy_amount); 369 std::memcpy(host_ptr, src_buffer, copy_amount);
387 break; 370 break;
388 } 371 }
@@ -406,7 +389,7 @@ struct Memory::Impl {
406 } 389 }
407 390
408 void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) { 391 void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) {
409 const auto& page_table = process.VMManager().page_table; 392 const auto& page_table = process.PageTable().PageTableImpl();
410 std::size_t remaining_size = size; 393 std::size_t remaining_size = size;
411 std::size_t page_index = dest_addr >> PAGE_BITS; 394 std::size_t page_index = dest_addr >> PAGE_BITS;
412 std::size_t page_offset = dest_addr & PAGE_MASK; 395 std::size_t page_offset = dest_addr & PAGE_MASK;
@@ -432,7 +415,7 @@ struct Memory::Impl {
432 break; 415 break;
433 } 416 }
434 case Common::PageType::RasterizerCachedMemory: { 417 case Common::PageType::RasterizerCachedMemory: {
435 u8* const host_ptr = GetPointerFromVMA(process, current_vaddr); 418 u8* const host_ptr{GetPointerFromRasterizerCachedMemory(current_vaddr)};
436 system.GPU().InvalidateRegion(current_vaddr, copy_amount); 419 system.GPU().InvalidateRegion(current_vaddr, copy_amount);
437 std::memset(host_ptr, 0, copy_amount); 420 std::memset(host_ptr, 0, copy_amount);
438 break; 421 break;
@@ -453,7 +436,7 @@ struct Memory::Impl {
453 436
454 void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, 437 void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
455 const std::size_t size) { 438 const std::size_t size) {
456 const auto& page_table = process.VMManager().page_table; 439 const auto& page_table = process.PageTable().PageTableImpl();
457 std::size_t remaining_size = size; 440 std::size_t remaining_size = size;
458 std::size_t page_index = src_addr >> PAGE_BITS; 441 std::size_t page_index = src_addr >> PAGE_BITS;
459 std::size_t page_offset = src_addr & PAGE_MASK; 442 std::size_t page_offset = src_addr & PAGE_MASK;
@@ -479,7 +462,7 @@ struct Memory::Impl {
479 break; 462 break;
480 } 463 }
481 case Common::PageType::RasterizerCachedMemory: { 464 case Common::PageType::RasterizerCachedMemory: {
482 const u8* const host_ptr = GetPointerFromVMA(process, current_vaddr); 465 const u8* const host_ptr{GetPointerFromRasterizerCachedMemory(current_vaddr)};
483 system.GPU().FlushRegion(current_vaddr, copy_amount); 466 system.GPU().FlushRegion(current_vaddr, copy_amount);
484 WriteBlock(process, dest_addr, host_ptr, copy_amount); 467 WriteBlock(process, dest_addr, host_ptr, copy_amount);
485 break; 468 break;
@@ -512,7 +495,7 @@ struct Memory::Impl {
512 495
513 u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1; 496 u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1;
514 for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) { 497 for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) {
515 Common::PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; 498 Common::PageType& page_type{current_page_table->attributes[vaddr >> PAGE_BITS]};
516 499
517 if (cached) { 500 if (cached) {
518 // Switch page type to cached if now cached 501 // Switch page type to cached if now cached
@@ -544,7 +527,7 @@ struct Memory::Impl {
544 // that this area is already unmarked as cached. 527 // that this area is already unmarked as cached.
545 break; 528 break;
546 case Common::PageType::RasterizerCachedMemory: { 529 case Common::PageType::RasterizerCachedMemory: {
547 u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); 530 u8* pointer{GetPointerFromRasterizerCachedMemory(vaddr & ~PAGE_MASK)};
548 if (pointer == nullptr) { 531 if (pointer == nullptr) {
549 // It's possible that this function has been called while updating the 532 // It's possible that this function has been called while updating the
550 // pagetable after unmapping a VMA. In that case the underlying VMA will no 533 // pagetable after unmapping a VMA. In that case the underlying VMA will no
@@ -573,9 +556,9 @@ struct Memory::Impl {
573 * @param memory The memory to map. 556 * @param memory The memory to map.
574 * @param type The page type to map the memory as. 557 * @param type The page type to map the memory as.
575 */ 558 */
576 void MapPages(Common::PageTable& page_table, VAddr base, u64 size, u8* memory, 559 void MapPages(Common::PageTable& page_table, VAddr base, u64 size, PAddr target,
577 Common::PageType type) { 560 Common::PageType type) {
578 LOG_DEBUG(HW_Memory, "Mapping {} onto {:016X}-{:016X}", fmt::ptr(memory), base * PAGE_SIZE, 561 LOG_DEBUG(HW_Memory, "Mapping {:016X} onto {:016X}-{:016X}", target, base * PAGE_SIZE,
579 (base + size) * PAGE_SIZE); 562 (base + size) * PAGE_SIZE);
580 563
581 // During boot, current_page_table might not be set yet, in which case we need not flush 564 // During boot, current_page_table might not be set yet, in which case we need not flush
@@ -593,19 +576,26 @@ struct Memory::Impl {
593 ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}", 576 ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}",
594 base + page_table.pointers.size()); 577 base + page_table.pointers.size());
595 578
596 std::fill(page_table.attributes.begin() + base, page_table.attributes.begin() + end, type); 579 if (!target) {
580 while (base != end) {
581 page_table.pointers[base] = nullptr;
582 page_table.attributes[base] = type;
583 page_table.backing_addr[base] = 0;
597 584
598 if (memory == nullptr) { 585 base += 1;
599 std::fill(page_table.pointers.begin() + base, page_table.pointers.begin() + end, 586 }
600 memory);
601 } else { 587 } else {
602 while (base != end) { 588 while (base != end) {
603 page_table.pointers[base] = memory - (base << PAGE_BITS); 589 page_table.pointers[base] =
590 system.DeviceMemory().GetPointer(target) - (base << PAGE_BITS);
591 page_table.attributes[base] = type;
592 page_table.backing_addr[base] = target - (base << PAGE_BITS);
593
604 ASSERT_MSG(page_table.pointers[base], 594 ASSERT_MSG(page_table.pointers[base],
605 "memory mapping base yield a nullptr within the table"); 595 "memory mapping base yield a nullptr within the table");
606 596
607 base += 1; 597 base += 1;
608 memory += PAGE_SIZE; 598 target += PAGE_SIZE;
609 } 599 }
610 } 600 }
611 } 601 }
@@ -640,7 +630,7 @@ struct Memory::Impl {
640 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); 630 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
641 break; 631 break;
642 case Common::PageType::RasterizerCachedMemory: { 632 case Common::PageType::RasterizerCachedMemory: {
643 const u8* const host_ptr = GetPointerFromVMA(vaddr); 633 const u8* const host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)};
644 system.GPU().FlushRegion(vaddr, sizeof(T)); 634 system.GPU().FlushRegion(vaddr, sizeof(T));
645 T value; 635 T value;
646 std::memcpy(&value, host_ptr, sizeof(T)); 636 std::memcpy(&value, host_ptr, sizeof(T));
@@ -682,7 +672,7 @@ struct Memory::Impl {
682 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); 672 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
683 break; 673 break;
684 case Common::PageType::RasterizerCachedMemory: { 674 case Common::PageType::RasterizerCachedMemory: {
685 u8* const host_ptr{GetPointerFromVMA(vaddr)}; 675 u8* const host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)};
686 system.GPU().InvalidateRegion(vaddr, sizeof(T)); 676 system.GPU().InvalidateRegion(vaddr, sizeof(T));
687 std::memcpy(host_ptr, &data, sizeof(T)); 677 std::memcpy(host_ptr, &data, sizeof(T));
688 break; 678 break;
@@ -703,12 +693,7 @@ void Memory::SetCurrentPageTable(Kernel::Process& process) {
703 impl->SetCurrentPageTable(process); 693 impl->SetCurrentPageTable(process);
704} 694}
705 695
706void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, 696void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) {
707 Kernel::PhysicalMemory& memory, VAddr offset) {
708 impl->MapMemoryRegion(page_table, base, size, memory, offset);
709}
710
711void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, u8* target) {
712 impl->MapMemoryRegion(page_table, base, size, target); 697 impl->MapMemoryRegion(page_table, base, size, target);
713} 698}
714 699
@@ -845,4 +830,4 @@ bool IsKernelVirtualAddress(const VAddr vaddr) {
845 return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END; 830 return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END;
846} 831}
847 832
848} // namespace Memory 833} // namespace Core::Memory