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.cpp211
1 files changed, 74 insertions, 137 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index c3f4829d7..11609682a 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -44,44 +44,16 @@ struct Memory::Impl {
44 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory); 44 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
45 } 45 }
46 46
47 void MapIoRegion(Common::PageTable& page_table, VAddr base, u64 size,
48 Common::MemoryHookPointer mmio_handler) {
49 UNIMPLEMENTED();
50 }
51
52 void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) { 47 void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
53 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size); 48 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
54 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base); 49 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
55 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped); 50 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped);
56 } 51 }
57 52
58 void AddDebugHook(Common::PageTable& page_table, VAddr base, u64 size,
59 Common::MemoryHookPointer hook) {
60 UNIMPLEMENTED();
61 }
62
63 void RemoveDebugHook(Common::PageTable& page_table, VAddr base, u64 size,
64 Common::MemoryHookPointer hook) {
65 UNIMPLEMENTED();
66 }
67
68 bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const { 53 bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const {
69 const auto& page_table = process.PageTable().PageTableImpl(); 54 const auto& page_table = process.PageTable().PageTableImpl();
70 55 const auto [pointer, type] = page_table.pointers[vaddr >> PAGE_BITS].PointerType();
71 const u8* const page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; 56 return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory;
72 if (page_pointer != nullptr) {
73 return true;
74 }
75
76 if (page_table.attributes[vaddr >> PAGE_BITS] == Common::PageType::RasterizerCachedMemory) {
77 return true;
78 }
79
80 if (page_table.attributes[vaddr >> PAGE_BITS] != Common::PageType::Special) {
81 return false;
82 }
83
84 return false;
85 } 57 }
86 58
87 bool IsValidVirtualAddress(VAddr vaddr) const { 59 bool IsValidVirtualAddress(VAddr vaddr) const {
@@ -99,17 +71,15 @@ struct Memory::Impl {
99 } 71 }
100 72
101 u8* GetPointer(const VAddr vaddr) const { 73 u8* GetPointer(const VAddr vaddr) const {
102 u8* const page_pointer{current_page_table->pointers[vaddr >> PAGE_BITS]}; 74 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw();
103 if (page_pointer) { 75 if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
104 return page_pointer + vaddr; 76 return pointer + vaddr;
105 } 77 }
106 78 const auto type = Common::PageTable::PageInfo::ExtractType(raw_pointer);
107 if (current_page_table->attributes[vaddr >> PAGE_BITS] == 79 if (type == Common::PageType::RasterizerCachedMemory) {
108 Common::PageType::RasterizerCachedMemory) {
109 return GetPointerFromRasterizerCachedMemory(vaddr); 80 return GetPointerFromRasterizerCachedMemory(vaddr);
110 } 81 }
111 82 return nullptr;
112 return {};
113 } 83 }
114 84
115 u8 Read8(const VAddr addr) { 85 u8 Read8(const VAddr addr) {
@@ -120,9 +90,9 @@ struct Memory::Impl {
120 if ((addr & 1) == 0) { 90 if ((addr & 1) == 0) {
121 return Read<u16_le>(addr); 91 return Read<u16_le>(addr);
122 } else { 92 } else {
123 const u8 a{Read<u8>(addr)}; 93 const u32 a{Read<u8>(addr)};
124 const u8 b{Read<u8>(addr + sizeof(u8))}; 94 const u32 b{Read<u8>(addr + sizeof(u8))};
125 return (static_cast<u16>(b) << 8) | a; 95 return static_cast<u16>((b << 8) | a);
126 } 96 }
127 } 97 }
128 98
@@ -130,9 +100,9 @@ struct Memory::Impl {
130 if ((addr & 3) == 0) { 100 if ((addr & 3) == 0) {
131 return Read<u32_le>(addr); 101 return Read<u32_le>(addr);
132 } else { 102 } else {
133 const u16 a{Read16(addr)}; 103 const u32 a{Read16(addr)};
134 const u16 b{Read16(addr + sizeof(u16))}; 104 const u32 b{Read16(addr + sizeof(u16))};
135 return (static_cast<u32>(b) << 16) | a; 105 return (b << 16) | a;
136 } 106 }
137 } 107 }
138 108
@@ -221,7 +191,8 @@ struct Memory::Impl {
221 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 191 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
222 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 192 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
223 193
224 switch (page_table.attributes[page_index]) { 194 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
195 switch (type) {
225 case Common::PageType::Unmapped: { 196 case Common::PageType::Unmapped: {
226 LOG_ERROR(HW_Memory, 197 LOG_ERROR(HW_Memory,
227 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 198 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -230,10 +201,8 @@ struct Memory::Impl {
230 break; 201 break;
231 } 202 }
232 case Common::PageType::Memory: { 203 case Common::PageType::Memory: {
233 DEBUG_ASSERT(page_table.pointers[page_index]); 204 DEBUG_ASSERT(pointer);
234 205 const u8* const src_ptr = pointer + page_offset + (page_index << PAGE_BITS);
235 const u8* const src_ptr =
236 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
237 std::memcpy(dest_buffer, src_ptr, copy_amount); 206 std::memcpy(dest_buffer, src_ptr, copy_amount);
238 break; 207 break;
239 } 208 }
@@ -267,7 +236,8 @@ struct Memory::Impl {
267 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 236 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
268 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 237 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
269 238
270 switch (page_table.attributes[page_index]) { 239 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
240 switch (type) {
271 case Common::PageType::Unmapped: { 241 case Common::PageType::Unmapped: {
272 LOG_ERROR(HW_Memory, 242 LOG_ERROR(HW_Memory,
273 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 243 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -276,10 +246,8 @@ struct Memory::Impl {
276 break; 246 break;
277 } 247 }
278 case Common::PageType::Memory: { 248 case Common::PageType::Memory: {
279 DEBUG_ASSERT(page_table.pointers[page_index]); 249 DEBUG_ASSERT(pointer);
280 250 const u8* const src_ptr = pointer + page_offset + (page_index << PAGE_BITS);
281 const u8* const src_ptr =
282 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
283 std::memcpy(dest_buffer, src_ptr, copy_amount); 251 std::memcpy(dest_buffer, src_ptr, copy_amount);
284 break; 252 break;
285 } 253 }
@@ -319,7 +287,8 @@ struct Memory::Impl {
319 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 287 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
320 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 288 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
321 289
322 switch (page_table.attributes[page_index]) { 290 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
291 switch (type) {
323 case Common::PageType::Unmapped: { 292 case Common::PageType::Unmapped: {
324 LOG_ERROR(HW_Memory, 293 LOG_ERROR(HW_Memory,
325 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 294 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -327,10 +296,8 @@ struct Memory::Impl {
327 break; 296 break;
328 } 297 }
329 case Common::PageType::Memory: { 298 case Common::PageType::Memory: {
330 DEBUG_ASSERT(page_table.pointers[page_index]); 299 DEBUG_ASSERT(pointer);
331 300 u8* const dest_ptr = pointer + page_offset + (page_index << PAGE_BITS);
332 u8* const dest_ptr =
333 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
334 std::memcpy(dest_ptr, src_buffer, copy_amount); 301 std::memcpy(dest_ptr, src_buffer, copy_amount);
335 break; 302 break;
336 } 303 }
@@ -363,7 +330,8 @@ struct Memory::Impl {
363 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 330 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
364 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 331 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
365 332
366 switch (page_table.attributes[page_index]) { 333 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
334 switch (type) {
367 case Common::PageType::Unmapped: { 335 case Common::PageType::Unmapped: {
368 LOG_ERROR(HW_Memory, 336 LOG_ERROR(HW_Memory,
369 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 337 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -371,10 +339,8 @@ struct Memory::Impl {
371 break; 339 break;
372 } 340 }
373 case Common::PageType::Memory: { 341 case Common::PageType::Memory: {
374 DEBUG_ASSERT(page_table.pointers[page_index]); 342 DEBUG_ASSERT(pointer);
375 343 u8* const dest_ptr = pointer + page_offset + (page_index << PAGE_BITS);
376 u8* const dest_ptr =
377 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
378 std::memcpy(dest_ptr, src_buffer, copy_amount); 344 std::memcpy(dest_ptr, src_buffer, copy_amount);
379 break; 345 break;
380 } 346 }
@@ -413,7 +379,8 @@ struct Memory::Impl {
413 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 379 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
414 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 380 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
415 381
416 switch (page_table.attributes[page_index]) { 382 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
383 switch (type) {
417 case Common::PageType::Unmapped: { 384 case Common::PageType::Unmapped: {
418 LOG_ERROR(HW_Memory, 385 LOG_ERROR(HW_Memory,
419 "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 386 "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -421,10 +388,8 @@ struct Memory::Impl {
421 break; 388 break;
422 } 389 }
423 case Common::PageType::Memory: { 390 case Common::PageType::Memory: {
424 DEBUG_ASSERT(page_table.pointers[page_index]); 391 DEBUG_ASSERT(pointer);
425 392 u8* const dest_ptr = pointer + page_offset + (page_index << PAGE_BITS);
426 u8* dest_ptr =
427 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
428 std::memset(dest_ptr, 0, copy_amount); 393 std::memset(dest_ptr, 0, copy_amount);
429 break; 394 break;
430 } 395 }
@@ -460,7 +425,8 @@ struct Memory::Impl {
460 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 425 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
461 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 426 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
462 427
463 switch (page_table.attributes[page_index]) { 428 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
429 switch (type) {
464 case Common::PageType::Unmapped: { 430 case Common::PageType::Unmapped: {
465 LOG_ERROR(HW_Memory, 431 LOG_ERROR(HW_Memory,
466 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 432 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -469,9 +435,8 @@ struct Memory::Impl {
469 break; 435 break;
470 } 436 }
471 case Common::PageType::Memory: { 437 case Common::PageType::Memory: {
472 DEBUG_ASSERT(page_table.pointers[page_index]); 438 DEBUG_ASSERT(pointer);
473 const u8* src_ptr = 439 const u8* src_ptr = pointer + page_offset + (page_index << PAGE_BITS);
474 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
475 WriteBlock(process, dest_addr, src_ptr, copy_amount); 440 WriteBlock(process, dest_addr, src_ptr, copy_amount);
476 break; 441 break;
477 } 442 }
@@ -501,16 +466,15 @@ struct Memory::Impl {
501 if (vaddr == 0) { 466 if (vaddr == 0) {
502 return; 467 return;
503 } 468 }
504
505 // Iterate over a contiguous CPU address space, which corresponds to the specified GPU 469 // Iterate over a contiguous CPU address space, which corresponds to the specified GPU
506 // address space, marking the region as un/cached. The region is marked un/cached at a 470 // address space, marking the region as un/cached. The region is marked un/cached at a
507 // granularity of CPU pages, hence why we iterate on a CPU page basis (note: GPU page size 471 // granularity of CPU pages, hence why we iterate on a CPU page basis (note: GPU page size
508 // is different). This assumes the specified GPU address region is contiguous as well. 472 // is different). This assumes the specified GPU address region is contiguous as well.
509 473
510 u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1; 474 const u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1;
511 for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) { 475 for (u64 i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) {
512 Common::PageType& page_type{current_page_table->attributes[vaddr >> PAGE_BITS]}; 476 const Common::PageType page_type{
513 477 current_page_table->pointers[vaddr >> PAGE_BITS].Type()};
514 if (cached) { 478 if (cached) {
515 // Switch page type to cached if now cached 479 // Switch page type to cached if now cached
516 switch (page_type) { 480 switch (page_type) {
@@ -519,8 +483,8 @@ struct Memory::Impl {
519 // space, for example, a system module need not have a VRAM mapping. 483 // space, for example, a system module need not have a VRAM mapping.
520 break; 484 break;
521 case Common::PageType::Memory: 485 case Common::PageType::Memory:
522 page_type = Common::PageType::RasterizerCachedMemory; 486 current_page_table->pointers[vaddr >> PAGE_BITS].Store(
523 current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; 487 nullptr, Common::PageType::RasterizerCachedMemory);
524 break; 488 break;
525 case Common::PageType::RasterizerCachedMemory: 489 case Common::PageType::RasterizerCachedMemory:
526 // There can be more than one GPU region mapped per CPU region, so it's common 490 // There can be more than one GPU region mapped per CPU region, so it's common
@@ -541,16 +505,16 @@ struct Memory::Impl {
541 // that this area is already unmarked as cached. 505 // that this area is already unmarked as cached.
542 break; 506 break;
543 case Common::PageType::RasterizerCachedMemory: { 507 case Common::PageType::RasterizerCachedMemory: {
544 u8* pointer{GetPointerFromRasterizerCachedMemory(vaddr & ~PAGE_MASK)}; 508 u8* const pointer{GetPointerFromRasterizerCachedMemory(vaddr & ~PAGE_MASK)};
545 if (pointer == nullptr) { 509 if (pointer == nullptr) {
546 // It's possible that this function has been called while updating the 510 // It's possible that this function has been called while updating the
547 // pagetable after unmapping a VMA. In that case the underlying VMA will no 511 // pagetable after unmapping a VMA. In that case the underlying VMA will no
548 // longer exist, and we should just leave the pagetable entry blank. 512 // longer exist, and we should just leave the pagetable entry blank.
549 page_type = Common::PageType::Unmapped; 513 current_page_table->pointers[vaddr >> PAGE_BITS].Store(
514 nullptr, Common::PageType::Unmapped);
550 } else { 515 } else {
551 current_page_table->pointers[vaddr >> PAGE_BITS] = 516 current_page_table->pointers[vaddr >> PAGE_BITS].Store(
552 pointer - (vaddr & ~PAGE_MASK); 517 pointer - (vaddr & ~PAGE_MASK), Common::PageType::Memory);
553 page_type = Common::PageType::Memory;
554 } 518 }
555 break; 519 break;
556 } 520 }
@@ -580,7 +544,7 @@ struct Memory::Impl {
580 auto& gpu = system.GPU(); 544 auto& gpu = system.GPU();
581 for (u64 i = 0; i < size; i++) { 545 for (u64 i = 0; i < size; i++) {
582 const auto page = base + i; 546 const auto page = base + i;
583 if (page_table.attributes[page] == Common::PageType::RasterizerCachedMemory) { 547 if (page_table.pointers[page].Type() == Common::PageType::RasterizerCachedMemory) {
584 gpu.FlushAndInvalidateRegion(page << PAGE_BITS, PAGE_SIZE); 548 gpu.FlushAndInvalidateRegion(page << PAGE_BITS, PAGE_SIZE);
585 } 549 }
586 } 550 }
@@ -595,20 +559,18 @@ struct Memory::Impl {
595 "Mapping memory page without a pointer @ {:016x}", base * PAGE_SIZE); 559 "Mapping memory page without a pointer @ {:016x}", base * PAGE_SIZE);
596 560
597 while (base != end) { 561 while (base != end) {
598 page_table.attributes[base] = type; 562 page_table.pointers[base].Store(nullptr, type);
599 page_table.pointers[base] = nullptr;
600 page_table.backing_addr[base] = 0; 563 page_table.backing_addr[base] = 0;
601 564
602 base += 1; 565 base += 1;
603 } 566 }
604 } else { 567 } else {
605 while (base != end) { 568 while (base != end) {
606 page_table.pointers[base] = 569 page_table.pointers[base].Store(
607 system.DeviceMemory().GetPointer(target) - (base << PAGE_BITS); 570 system.DeviceMemory().GetPointer(target) - (base << PAGE_BITS), type);
608 page_table.attributes[base] = type;
609 page_table.backing_addr[base] = target - (base << PAGE_BITS); 571 page_table.backing_addr[base] = target - (base << PAGE_BITS);
610 572
611 ASSERT_MSG(page_table.pointers[base], 573 ASSERT_MSG(page_table.pointers[base].Pointer(),
612 "memory mapping base yield a nullptr within the table"); 574 "memory mapping base yield a nullptr within the table");
613 575
614 base += 1; 576 base += 1;
@@ -630,16 +592,14 @@ struct Memory::Impl {
630 */ 592 */
631 template <typename T> 593 template <typename T>
632 T Read(const VAddr vaddr) { 594 T Read(const VAddr vaddr) {
633 const u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 595 // Avoid adding any extra logic to this fast-path block
634 if (page_pointer != nullptr) { 596 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw();
635 // NOTE: Avoid adding any extra logic to this fast-path block 597 if (const u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
636 T value; 598 T value;
637 std::memcpy(&value, &page_pointer[vaddr], sizeof(T)); 599 std::memcpy(&value, &pointer[vaddr], sizeof(T));
638 return value; 600 return value;
639 } 601 }
640 602 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
641 const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
642 switch (type) {
643 case Common::PageType::Unmapped: 603 case Common::PageType::Unmapped:
644 LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr); 604 LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr);
645 return 0; 605 return 0;
@@ -667,20 +627,16 @@ struct Memory::Impl {
667 * @tparam T The data type to write to memory. This type *must* be 627 * @tparam T The data type to write to memory. This type *must* be
668 * trivially copyable, otherwise the behavior of this function 628 * trivially copyable, otherwise the behavior of this function
669 * is undefined. 629 * is undefined.
670 *
671 * @returns The instance of T write to the specified virtual address.
672 */ 630 */
673 template <typename T> 631 template <typename T>
674 void Write(const VAddr vaddr, const T data) { 632 void Write(const VAddr vaddr, const T data) {
675 u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 633 // Avoid adding any extra logic to this fast-path block
676 if (page_pointer != nullptr) { 634 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw();
677 // NOTE: Avoid adding any extra logic to this fast-path block 635 if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
678 std::memcpy(&page_pointer[vaddr], &data, sizeof(T)); 636 std::memcpy(&pointer[vaddr], &data, sizeof(T));
679 return; 637 return;
680 } 638 }
681 639 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
682 const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
683 switch (type) {
684 case Common::PageType::Unmapped: 640 case Common::PageType::Unmapped:
685 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, 641 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8,
686 static_cast<u32>(data), vaddr); 642 static_cast<u32>(data), vaddr);
@@ -701,15 +657,13 @@ struct Memory::Impl {
701 657
702 template <typename T> 658 template <typename T>
703 bool WriteExclusive(const VAddr vaddr, const T data, const T expected) { 659 bool WriteExclusive(const VAddr vaddr, const T data, const T expected) {
704 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 660 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw();
705 if (page_pointer != nullptr) { 661 if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
706 // NOTE: Avoid adding any extra logic to this fast-path block 662 // NOTE: Avoid adding any extra logic to this fast-path block
707 auto* pointer = reinterpret_cast<volatile T*>(&page_pointer[vaddr]); 663 const auto volatile_pointer = reinterpret_cast<volatile T*>(&pointer[vaddr]);
708 return Common::AtomicCompareAndSwap(pointer, data, expected); 664 return Common::AtomicCompareAndSwap(volatile_pointer, data, expected);
709 } 665 }
710 666 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
711 const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
712 switch (type) {
713 case Common::PageType::Unmapped: 667 case Common::PageType::Unmapped:
714 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, 668 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8,
715 static_cast<u32>(data), vaddr); 669 static_cast<u32>(data), vaddr);
@@ -730,15 +684,13 @@ struct Memory::Impl {
730 } 684 }
731 685
732 bool WriteExclusive128(const VAddr vaddr, const u128 data, const u128 expected) { 686 bool WriteExclusive128(const VAddr vaddr, const u128 data, const u128 expected) {
733 u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 687 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw();
734 if (page_pointer != nullptr) { 688 if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
735 // NOTE: Avoid adding any extra logic to this fast-path block 689 // NOTE: Avoid adding any extra logic to this fast-path block
736 auto* pointer = reinterpret_cast<volatile u64*>(&page_pointer[vaddr]); 690 const auto volatile_pointer = reinterpret_cast<volatile u64*>(&pointer[vaddr]);
737 return Common::AtomicCompareAndSwap(pointer, data, expected); 691 return Common::AtomicCompareAndSwap(volatile_pointer, data, expected);
738 } 692 }
739 693 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
740 const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
741 switch (type) {
742 case Common::PageType::Unmapped: 694 case Common::PageType::Unmapped:
743 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}{:016X}", sizeof(data) * 8, 695 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}{:016X}", sizeof(data) * 8,
744 static_cast<u64>(data[1]), static_cast<u64>(data[0]), vaddr); 696 static_cast<u64>(data[1]), static_cast<u64>(data[0]), vaddr);
@@ -773,25 +725,10 @@ void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size
773 impl->MapMemoryRegion(page_table, base, size, target); 725 impl->MapMemoryRegion(page_table, base, size, target);
774} 726}
775 727
776void Memory::MapIoRegion(Common::PageTable& page_table, VAddr base, u64 size,
777 Common::MemoryHookPointer mmio_handler) {
778 impl->MapIoRegion(page_table, base, size, std::move(mmio_handler));
779}
780
781void Memory::UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) { 728void Memory::UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
782 impl->UnmapRegion(page_table, base, size); 729 impl->UnmapRegion(page_table, base, size);
783} 730}
784 731
785void Memory::AddDebugHook(Common::PageTable& page_table, VAddr base, u64 size,
786 Common::MemoryHookPointer hook) {
787 impl->AddDebugHook(page_table, base, size, std::move(hook));
788}
789
790void Memory::RemoveDebugHook(Common::PageTable& page_table, VAddr base, u64 size,
791 Common::MemoryHookPointer hook) {
792 impl->RemoveDebugHook(page_table, base, size, std::move(hook));
793}
794
795bool Memory::IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const { 732bool Memory::IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const {
796 return impl->IsValidVirtualAddress(process, vaddr); 733 return impl->IsValidVirtualAddress(process, vaddr);
797} 734}