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.cpp187
1 files changed, 64 insertions, 123 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 54a848936..f209c4949 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -4,7 +4,6 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <cstring> 6#include <cstring>
7#include <mutex>
8#include <optional> 7#include <optional>
9#include <utility> 8#include <utility>
10 9
@@ -68,21 +67,8 @@ struct Memory::Impl {
68 67
69 bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const { 68 bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const {
70 const auto& page_table = process.PageTable().PageTableImpl(); 69 const auto& page_table = process.PageTable().PageTableImpl();
71 70 const auto [pointer, type] = page_table.pointers[vaddr >> PAGE_BITS].PointerType();
72 const u8* const page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; 71 return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory;
73 if (page_pointer != nullptr) {
74 return true;
75 }
76
77 if (page_table.attributes[vaddr >> PAGE_BITS] == Common::PageType::RasterizerCachedMemory) {
78 return true;
79 }
80
81 if (page_table.attributes[vaddr >> PAGE_BITS] != Common::PageType::Special) {
82 return false;
83 }
84
85 return false;
86 } 72 }
87 73
88 bool IsValidVirtualAddress(VAddr vaddr) const { 74 bool IsValidVirtualAddress(VAddr vaddr) const {
@@ -100,17 +86,15 @@ struct Memory::Impl {
100 } 86 }
101 87
102 u8* GetPointer(const VAddr vaddr) const { 88 u8* GetPointer(const VAddr vaddr) const {
103 u8* const page_pointer{current_page_table->pointers[vaddr >> PAGE_BITS]}; 89 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw();
104 if (page_pointer) { 90 if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
105 return page_pointer + vaddr; 91 return pointer + vaddr;
106 } 92 }
107 93 const auto type = Common::PageTable::PageInfo::ExtractType(raw_pointer);
108 if (current_page_table->attributes[vaddr >> PAGE_BITS] == 94 if (type == Common::PageType::RasterizerCachedMemory) {
109 Common::PageType::RasterizerCachedMemory) {
110 return GetPointerFromRasterizerCachedMemory(vaddr); 95 return GetPointerFromRasterizerCachedMemory(vaddr);
111 } 96 }
112 97 return nullptr;
113 return {};
114 } 98 }
115 99
116 u8 Read8(const VAddr addr) { 100 u8 Read8(const VAddr addr) {
@@ -222,7 +206,8 @@ struct Memory::Impl {
222 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 206 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
223 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 207 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
224 208
225 switch (page_table.attributes[page_index]) { 209 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
210 switch (type) {
226 case Common::PageType::Unmapped: { 211 case Common::PageType::Unmapped: {
227 LOG_ERROR(HW_Memory, 212 LOG_ERROR(HW_Memory,
228 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 213 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -231,10 +216,8 @@ struct Memory::Impl {
231 break; 216 break;
232 } 217 }
233 case Common::PageType::Memory: { 218 case Common::PageType::Memory: {
234 DEBUG_ASSERT(page_table.pointers[page_index]); 219 DEBUG_ASSERT(pointer);
235 220 const u8* const src_ptr = pointer + page_offset + (page_index << PAGE_BITS);
236 const u8* const src_ptr =
237 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
238 std::memcpy(dest_buffer, src_ptr, copy_amount); 221 std::memcpy(dest_buffer, src_ptr, copy_amount);
239 break; 222 break;
240 } 223 }
@@ -268,7 +251,8 @@ struct Memory::Impl {
268 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 251 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
269 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 252 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
270 253
271 switch (page_table.attributes[page_index]) { 254 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
255 switch (type) {
272 case Common::PageType::Unmapped: { 256 case Common::PageType::Unmapped: {
273 LOG_ERROR(HW_Memory, 257 LOG_ERROR(HW_Memory,
274 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 258 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -277,10 +261,8 @@ struct Memory::Impl {
277 break; 261 break;
278 } 262 }
279 case Common::PageType::Memory: { 263 case Common::PageType::Memory: {
280 DEBUG_ASSERT(page_table.pointers[page_index]); 264 DEBUG_ASSERT(pointer);
281 265 const u8* const src_ptr = pointer + page_offset + (page_index << PAGE_BITS);
282 const u8* const src_ptr =
283 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
284 std::memcpy(dest_buffer, src_ptr, copy_amount); 266 std::memcpy(dest_buffer, src_ptr, copy_amount);
285 break; 267 break;
286 } 268 }
@@ -320,7 +302,8 @@ struct Memory::Impl {
320 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 302 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
321 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 303 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
322 304
323 switch (page_table.attributes[page_index]) { 305 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
306 switch (type) {
324 case Common::PageType::Unmapped: { 307 case Common::PageType::Unmapped: {
325 LOG_ERROR(HW_Memory, 308 LOG_ERROR(HW_Memory,
326 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 309 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -328,10 +311,8 @@ struct Memory::Impl {
328 break; 311 break;
329 } 312 }
330 case Common::PageType::Memory: { 313 case Common::PageType::Memory: {
331 DEBUG_ASSERT(page_table.pointers[page_index]); 314 DEBUG_ASSERT(pointer);
332 315 u8* const dest_ptr = pointer + page_offset + (page_index << PAGE_BITS);
333 u8* const dest_ptr =
334 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
335 std::memcpy(dest_ptr, src_buffer, copy_amount); 316 std::memcpy(dest_ptr, src_buffer, copy_amount);
336 break; 317 break;
337 } 318 }
@@ -364,7 +345,8 @@ struct Memory::Impl {
364 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 345 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
365 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 346 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
366 347
367 switch (page_table.attributes[page_index]) { 348 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
349 switch (type) {
368 case Common::PageType::Unmapped: { 350 case Common::PageType::Unmapped: {
369 LOG_ERROR(HW_Memory, 351 LOG_ERROR(HW_Memory,
370 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 352 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -372,10 +354,8 @@ struct Memory::Impl {
372 break; 354 break;
373 } 355 }
374 case Common::PageType::Memory: { 356 case Common::PageType::Memory: {
375 DEBUG_ASSERT(page_table.pointers[page_index]); 357 DEBUG_ASSERT(pointer);
376 358 u8* const dest_ptr = pointer + page_offset + (page_index << PAGE_BITS);
377 u8* const dest_ptr =
378 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
379 std::memcpy(dest_ptr, src_buffer, copy_amount); 359 std::memcpy(dest_ptr, src_buffer, copy_amount);
380 break; 360 break;
381 } 361 }
@@ -414,7 +394,8 @@ struct Memory::Impl {
414 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 394 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
415 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 395 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
416 396
417 switch (page_table.attributes[page_index]) { 397 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
398 switch (type) {
418 case Common::PageType::Unmapped: { 399 case Common::PageType::Unmapped: {
419 LOG_ERROR(HW_Memory, 400 LOG_ERROR(HW_Memory,
420 "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 401 "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -422,10 +403,8 @@ struct Memory::Impl {
422 break; 403 break;
423 } 404 }
424 case Common::PageType::Memory: { 405 case Common::PageType::Memory: {
425 DEBUG_ASSERT(page_table.pointers[page_index]); 406 DEBUG_ASSERT(pointer);
426 407 u8* const dest_ptr = pointer + page_offset + (page_index << PAGE_BITS);
427 u8* dest_ptr =
428 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
429 std::memset(dest_ptr, 0, copy_amount); 408 std::memset(dest_ptr, 0, copy_amount);
430 break; 409 break;
431 } 410 }
@@ -461,7 +440,8 @@ struct Memory::Impl {
461 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size); 440 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
462 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 441 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
463 442
464 switch (page_table.attributes[page_index]) { 443 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
444 switch (type) {
465 case Common::PageType::Unmapped: { 445 case Common::PageType::Unmapped: {
466 LOG_ERROR(HW_Memory, 446 LOG_ERROR(HW_Memory,
467 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 447 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
@@ -470,9 +450,8 @@ struct Memory::Impl {
470 break; 450 break;
471 } 451 }
472 case Common::PageType::Memory: { 452 case Common::PageType::Memory: {
473 DEBUG_ASSERT(page_table.pointers[page_index]); 453 DEBUG_ASSERT(pointer);
474 const u8* src_ptr = 454 const u8* src_ptr = pointer + page_offset + (page_index << PAGE_BITS);
475 page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
476 WriteBlock(process, dest_addr, src_ptr, copy_amount); 455 WriteBlock(process, dest_addr, src_ptr, copy_amount);
477 break; 456 break;
478 } 457 }
@@ -498,34 +477,19 @@ struct Memory::Impl {
498 return CopyBlock(*system.CurrentProcess(), dest_addr, src_addr, size); 477 return CopyBlock(*system.CurrentProcess(), dest_addr, src_addr, size);
499 } 478 }
500 479
501 struct PageEntry {
502 u8* const pointer;
503 const Common::PageType attribute;
504 };
505
506 PageEntry SafePageEntry(std::size_t base) const {
507 std::lock_guard lock{rasterizer_cache_guard};
508 return {
509 .pointer = current_page_table->pointers[base],
510 .attribute = current_page_table->attributes[base],
511 };
512 }
513
514 void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { 480 void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) {
515 std::lock_guard lock{rasterizer_cache_guard};
516 if (vaddr == 0) { 481 if (vaddr == 0) {
517 return; 482 return;
518 } 483 }
519
520 // Iterate over a contiguous CPU address space, which corresponds to the specified GPU 484 // Iterate over a contiguous CPU address space, which corresponds to the specified GPU
521 // address space, marking the region as un/cached. The region is marked un/cached at a 485 // address space, marking the region as un/cached. The region is marked un/cached at a
522 // granularity of CPU pages, hence why we iterate on a CPU page basis (note: GPU page size 486 // granularity of CPU pages, hence why we iterate on a CPU page basis (note: GPU page size
523 // is different). This assumes the specified GPU address region is contiguous as well. 487 // is different). This assumes the specified GPU address region is contiguous as well.
524 488
525 u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1; 489 const u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1;
526 for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) { 490 for (u64 i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) {
527 Common::PageType& page_type{current_page_table->attributes[vaddr >> PAGE_BITS]}; 491 const Common::PageType page_type{
528 492 current_page_table->pointers[vaddr >> PAGE_BITS].Type()};
529 if (cached) { 493 if (cached) {
530 // Switch page type to cached if now cached 494 // Switch page type to cached if now cached
531 switch (page_type) { 495 switch (page_type) {
@@ -534,8 +498,8 @@ struct Memory::Impl {
534 // space, for example, a system module need not have a VRAM mapping. 498 // space, for example, a system module need not have a VRAM mapping.
535 break; 499 break;
536 case Common::PageType::Memory: 500 case Common::PageType::Memory:
537 page_type = Common::PageType::RasterizerCachedMemory; 501 current_page_table->pointers[vaddr >> PAGE_BITS].Store(
538 current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; 502 nullptr, Common::PageType::RasterizerCachedMemory);
539 break; 503 break;
540 case Common::PageType::RasterizerCachedMemory: 504 case Common::PageType::RasterizerCachedMemory:
541 // There can be more than one GPU region mapped per CPU region, so it's common 505 // There can be more than one GPU region mapped per CPU region, so it's common
@@ -556,16 +520,16 @@ struct Memory::Impl {
556 // that this area is already unmarked as cached. 520 // that this area is already unmarked as cached.
557 break; 521 break;
558 case Common::PageType::RasterizerCachedMemory: { 522 case Common::PageType::RasterizerCachedMemory: {
559 u8* pointer{GetPointerFromRasterizerCachedMemory(vaddr & ~PAGE_MASK)}; 523 u8* const pointer{GetPointerFromRasterizerCachedMemory(vaddr & ~PAGE_MASK)};
560 if (pointer == nullptr) { 524 if (pointer == nullptr) {
561 // It's possible that this function has been called while updating the 525 // It's possible that this function has been called while updating the
562 // pagetable after unmapping a VMA. In that case the underlying VMA will no 526 // pagetable after unmapping a VMA. In that case the underlying VMA will no
563 // longer exist, and we should just leave the pagetable entry blank. 527 // longer exist, and we should just leave the pagetable entry blank.
564 page_type = Common::PageType::Unmapped; 528 current_page_table->pointers[vaddr >> PAGE_BITS].Store(
529 nullptr, Common::PageType::Unmapped);
565 } else { 530 } else {
566 current_page_table->pointers[vaddr >> PAGE_BITS] = 531 current_page_table->pointers[vaddr >> PAGE_BITS].Store(
567 pointer - (vaddr & ~PAGE_MASK); 532 pointer - (vaddr & ~PAGE_MASK), Common::PageType::Memory);
568 page_type = Common::PageType::Memory;
569 } 533 }
570 break; 534 break;
571 } 535 }
@@ -595,7 +559,7 @@ struct Memory::Impl {
595 auto& gpu = system.GPU(); 559 auto& gpu = system.GPU();
596 for (u64 i = 0; i < size; i++) { 560 for (u64 i = 0; i < size; i++) {
597 const auto page = base + i; 561 const auto page = base + i;
598 if (page_table.attributes[page] == Common::PageType::RasterizerCachedMemory) { 562 if (page_table.pointers[page].Type() == Common::PageType::RasterizerCachedMemory) {
599 gpu.FlushAndInvalidateRegion(page << PAGE_BITS, PAGE_SIZE); 563 gpu.FlushAndInvalidateRegion(page << PAGE_BITS, PAGE_SIZE);
600 } 564 }
601 } 565 }
@@ -610,20 +574,18 @@ struct Memory::Impl {
610 "Mapping memory page without a pointer @ {:016x}", base * PAGE_SIZE); 574 "Mapping memory page without a pointer @ {:016x}", base * PAGE_SIZE);
611 575
612 while (base != end) { 576 while (base != end) {
613 page_table.attributes[base] = type; 577 page_table.pointers[base].Store(nullptr, type);
614 page_table.pointers[base] = nullptr;
615 page_table.backing_addr[base] = 0; 578 page_table.backing_addr[base] = 0;
616 579
617 base += 1; 580 base += 1;
618 } 581 }
619 } else { 582 } else {
620 while (base != end) { 583 while (base != end) {
621 page_table.pointers[base] = 584 page_table.pointers[base].Store(
622 system.DeviceMemory().GetPointer(target) - (base << PAGE_BITS); 585 system.DeviceMemory().GetPointer(target) - (base << PAGE_BITS), type);
623 page_table.attributes[base] = type;
624 page_table.backing_addr[base] = target - (base << PAGE_BITS); 586 page_table.backing_addr[base] = target - (base << PAGE_BITS);
625 587
626 ASSERT_MSG(page_table.pointers[base], 588 ASSERT_MSG(page_table.pointers[base].Pointer(),
627 "memory mapping base yield a nullptr within the table"); 589 "memory mapping base yield a nullptr within the table");
628 590
629 base += 1; 591 base += 1;
@@ -646,21 +608,13 @@ struct Memory::Impl {
646 template <typename T> 608 template <typename T>
647 T Read(const VAddr vaddr) { 609 T Read(const VAddr vaddr) {
648 // Avoid adding any extra logic to this fast-path block 610 // Avoid adding any extra logic to this fast-path block
649 if (const u8* const pointer = current_page_table->pointers[vaddr >> PAGE_BITS]) { 611 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw();
612 if (const u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
650 T value; 613 T value;
651 std::memcpy(&value, &pointer[vaddr], sizeof(T)); 614 std::memcpy(&value, &pointer[vaddr], sizeof(T));
652 return value; 615 return value;
653 } 616 }
654 617 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
655 // Otherwise, we need to grab the page with a lock, in case it is currently being modified
656 const auto entry = SafePageEntry(vaddr >> PAGE_BITS);
657 if (entry.pointer) {
658 T value;
659 std::memcpy(&value, &entry.pointer[vaddr], sizeof(T));
660 return value;
661 }
662
663 switch (entry.attribute) {
664 case Common::PageType::Unmapped: 618 case Common::PageType::Unmapped:
665 LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr); 619 LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr);
666 return 0; 620 return 0;
@@ -692,20 +646,12 @@ struct Memory::Impl {
692 template <typename T> 646 template <typename T>
693 void Write(const VAddr vaddr, const T data) { 647 void Write(const VAddr vaddr, const T data) {
694 // Avoid adding any extra logic to this fast-path block 648 // Avoid adding any extra logic to this fast-path block
695 if (u8* const pointer = current_page_table->pointers[vaddr >> PAGE_BITS]) { 649 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw();
650 if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
696 std::memcpy(&pointer[vaddr], &data, sizeof(T)); 651 std::memcpy(&pointer[vaddr], &data, sizeof(T));
697 return; 652 return;
698 } 653 }
699 654 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
700 // Otherwise, we need to grab the page with a lock, in case it is currently being modified
701 const auto entry = SafePageEntry(vaddr >> PAGE_BITS);
702 if (entry.pointer) {
703 // Memory was mapped, we are done
704 std::memcpy(&entry.pointer[vaddr], &data, sizeof(T));
705 return;
706 }
707
708 switch (entry.attribute) {
709 case Common::PageType::Unmapped: 655 case Common::PageType::Unmapped:
710 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, 656 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8,
711 static_cast<u32>(data), vaddr); 657 static_cast<u32>(data), vaddr);
@@ -726,15 +672,13 @@ struct Memory::Impl {
726 672
727 template <typename T> 673 template <typename T>
728 bool WriteExclusive(const VAddr vaddr, const T data, const T expected) { 674 bool WriteExclusive(const VAddr vaddr, const T data, const T expected) {
729 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 675 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw();
730 if (page_pointer != nullptr) { 676 if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
731 // NOTE: Avoid adding any extra logic to this fast-path block 677 // NOTE: Avoid adding any extra logic to this fast-path block
732 auto* pointer = reinterpret_cast<volatile T*>(&page_pointer[vaddr]); 678 const auto volatile_pointer = reinterpret_cast<volatile T*>(&pointer[vaddr]);
733 return Common::AtomicCompareAndSwap(pointer, data, expected); 679 return Common::AtomicCompareAndSwap(volatile_pointer, data, expected);
734 } 680 }
735 681 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
736 const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
737 switch (type) {
738 case Common::PageType::Unmapped: 682 case Common::PageType::Unmapped:
739 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, 683 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8,
740 static_cast<u32>(data), vaddr); 684 static_cast<u32>(data), vaddr);
@@ -755,15 +699,13 @@ struct Memory::Impl {
755 } 699 }
756 700
757 bool WriteExclusive128(const VAddr vaddr, const u128 data, const u128 expected) { 701 bool WriteExclusive128(const VAddr vaddr, const u128 data, const u128 expected) {
758 u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 702 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw();
759 if (page_pointer != nullptr) { 703 if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
760 // NOTE: Avoid adding any extra logic to this fast-path block 704 // NOTE: Avoid adding any extra logic to this fast-path block
761 auto* pointer = reinterpret_cast<volatile u64*>(&page_pointer[vaddr]); 705 const auto volatile_pointer = reinterpret_cast<volatile u64*>(&pointer[vaddr]);
762 return Common::AtomicCompareAndSwap(pointer, data, expected); 706 return Common::AtomicCompareAndSwap(volatile_pointer, data, expected);
763 } 707 }
764 708 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
765 const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
766 switch (type) {
767 case Common::PageType::Unmapped: 709 case Common::PageType::Unmapped:
768 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}{:016X}", sizeof(data) * 8, 710 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}{:016X}", sizeof(data) * 8,
769 static_cast<u64>(data[1]), static_cast<u64>(data[0]), vaddr); 711 static_cast<u64>(data[1]), static_cast<u64>(data[0]), vaddr);
@@ -783,7 +725,6 @@ struct Memory::Impl {
783 return true; 725 return true;
784 } 726 }
785 727
786 mutable std::mutex rasterizer_cache_guard;
787 Common::PageTable* current_page_table = nullptr; 728 Common::PageTable* current_page_table = nullptr;
788 Core::System& system; 729 Core::System& system;
789}; 730};