summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/memory.cpp52
1 files changed, 40 insertions, 12 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index b7f21698f..54a848936 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -4,6 +4,7 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <cstring> 6#include <cstring>
7#include <mutex>
7#include <optional> 8#include <optional>
8#include <utility> 9#include <utility>
9 10
@@ -497,7 +498,21 @@ struct Memory::Impl {
497 return CopyBlock(*system.CurrentProcess(), dest_addr, src_addr, size); 498 return CopyBlock(*system.CurrentProcess(), dest_addr, src_addr, size);
498 } 499 }
499 500
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
500 void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { 514 void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) {
515 std::lock_guard lock{rasterizer_cache_guard};
501 if (vaddr == 0) { 516 if (vaddr == 0) {
502 return; 517 return;
503 } 518 }
@@ -630,16 +645,22 @@ struct Memory::Impl {
630 */ 645 */
631 template <typename T> 646 template <typename T>
632 T Read(const VAddr vaddr) { 647 T Read(const VAddr vaddr) {
633 const u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 648 // Avoid adding any extra logic to this fast-path block
634 if (page_pointer != nullptr) { 649 if (const u8* const pointer = current_page_table->pointers[vaddr >> PAGE_BITS]) {
635 // NOTE: Avoid adding any extra logic to this fast-path block
636 T value; 650 T value;
637 std::memcpy(&value, &page_pointer[vaddr], sizeof(T)); 651 std::memcpy(&value, &pointer[vaddr], sizeof(T));
638 return value; 652 return value;
639 } 653 }
640 654
641 const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; 655 // Otherwise, we need to grab the page with a lock, in case it is currently being modified
642 switch (type) { 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) {
643 case Common::PageType::Unmapped: 664 case Common::PageType::Unmapped:
644 LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr); 665 LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr);
645 return 0; 666 return 0;
@@ -670,15 +691,21 @@ struct Memory::Impl {
670 */ 691 */
671 template <typename T> 692 template <typename T>
672 void Write(const VAddr vaddr, const T data) { 693 void Write(const VAddr vaddr, const T data) {
673 u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 694 // Avoid adding any extra logic to this fast-path block
674 if (page_pointer != nullptr) { 695 if (u8* const pointer = current_page_table->pointers[vaddr >> PAGE_BITS]) {
675 // NOTE: Avoid adding any extra logic to this fast-path block 696 std::memcpy(&pointer[vaddr], &data, sizeof(T));
676 std::memcpy(&page_pointer[vaddr], &data, sizeof(T));
677 return; 697 return;
678 } 698 }
679 699
680 const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; 700 // Otherwise, we need to grab the page with a lock, in case it is currently being modified
681 switch (type) { 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) {
682 case Common::PageType::Unmapped: 709 case Common::PageType::Unmapped:
683 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, 710 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8,
684 static_cast<u32>(data), vaddr); 711 static_cast<u32>(data), vaddr);
@@ -756,6 +783,7 @@ struct Memory::Impl {
756 return true; 783 return true;
757 } 784 }
758 785
786 mutable std::mutex rasterizer_cache_guard;
759 Common::PageTable* current_page_table = nullptr; 787 Common::PageTable* current_page_table = nullptr;
760 Core::System& system; 788 Core::System& system;
761}; 789};