diff options
Diffstat (limited to '')
| -rw-r--r-- | src/common/page_table.cpp | 1 | ||||
| -rw-r--r-- | src/common/page_table.h | 6 | ||||
| -rw-r--r-- | src/core/memory.cpp | 43 |
3 files changed, 46 insertions, 4 deletions
diff --git a/src/common/page_table.cpp b/src/common/page_table.cpp index 8fd8620fd..9fffd816f 100644 --- a/src/common/page_table.cpp +++ b/src/common/page_table.cpp | |||
| @@ -14,6 +14,7 @@ void PageTable::Resize(size_t address_space_width_in_bits, size_t page_size_in_b | |||
| 14 | const size_t num_page_table_entries{1ULL << (address_space_width_in_bits - page_size_in_bits)}; | 14 | const size_t num_page_table_entries{1ULL << (address_space_width_in_bits - page_size_in_bits)}; |
| 15 | pointers.resize(num_page_table_entries); | 15 | pointers.resize(num_page_table_entries); |
| 16 | backing_addr.resize(num_page_table_entries); | 16 | backing_addr.resize(num_page_table_entries); |
| 17 | current_address_space_width_in_bits = address_space_width_in_bits; | ||
| 17 | } | 18 | } |
| 18 | 19 | ||
| 19 | } // namespace Common | 20 | } // namespace Common |
diff --git a/src/common/page_table.h b/src/common/page_table.h index 61c5552e0..e92b66b2b 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h | |||
| @@ -98,6 +98,10 @@ struct PageTable { | |||
| 98 | */ | 98 | */ |
| 99 | void Resize(size_t address_space_width_in_bits, size_t page_size_in_bits); | 99 | void Resize(size_t address_space_width_in_bits, size_t page_size_in_bits); |
| 100 | 100 | ||
| 101 | size_t GetAddressSpaceBits() const { | ||
| 102 | return current_address_space_width_in_bits; | ||
| 103 | } | ||
| 104 | |||
| 101 | /** | 105 | /** |
| 102 | * Vector of memory pointers backing each page. An entry can only be non-null if the | 106 | * Vector of memory pointers backing each page. An entry can only be non-null if the |
| 103 | * corresponding attribute element is of type `Memory`. | 107 | * corresponding attribute element is of type `Memory`. |
| @@ -105,6 +109,8 @@ struct PageTable { | |||
| 105 | VirtualBuffer<PageInfo> pointers; | 109 | VirtualBuffer<PageInfo> pointers; |
| 106 | 110 | ||
| 107 | VirtualBuffer<u64> backing_addr; | 111 | VirtualBuffer<u64> backing_addr; |
| 112 | |||
| 113 | size_t current_address_space_width_in_bits; | ||
| 108 | }; | 114 | }; |
| 109 | 115 | ||
| 110 | } // namespace Common | 116 | } // namespace Common |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index bf2ef7816..9857278f6 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -591,7 +591,15 @@ struct Memory::Impl { | |||
| 591 | * @returns The instance of T read from the specified virtual address. | 591 | * @returns The instance of T read from the specified virtual address. |
| 592 | */ | 592 | */ |
| 593 | template <typename T> | 593 | template <typename T> |
| 594 | T Read(const VAddr vaddr) { | 594 | T Read(VAddr vaddr) { |
| 595 | // AARCH64 masks the upper 16 bit of all memory accesses | ||
| 596 | vaddr &= 0xffffffffffffLL; | ||
| 597 | |||
| 598 | if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { | ||
| 599 | LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr); | ||
| 600 | return 0; | ||
| 601 | } | ||
| 602 | |||
| 595 | // Avoid adding any extra logic to this fast-path block | 603 | // Avoid adding any extra logic to this fast-path block |
| 596 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); | 604 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); |
| 597 | if (const u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { | 605 | if (const u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { |
| @@ -629,7 +637,16 @@ struct Memory::Impl { | |||
| 629 | * is undefined. | 637 | * is undefined. |
| 630 | */ | 638 | */ |
| 631 | template <typename T> | 639 | template <typename T> |
| 632 | void Write(const VAddr vaddr, const T data) { | 640 | void Write(VAddr vaddr, const T data) { |
| 641 | // AARCH64 masks the upper 16 bit of all memory accesses | ||
| 642 | vaddr &= 0xffffffffffffLL; | ||
| 643 | |||
| 644 | if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { | ||
| 645 | LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, | ||
| 646 | static_cast<u32>(data), vaddr); | ||
| 647 | return; | ||
| 648 | } | ||
| 649 | |||
| 633 | // Avoid adding any extra logic to this fast-path block | 650 | // Avoid adding any extra logic to this fast-path block |
| 634 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); | 651 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); |
| 635 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { | 652 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { |
| @@ -656,7 +673,16 @@ struct Memory::Impl { | |||
| 656 | } | 673 | } |
| 657 | 674 | ||
| 658 | template <typename T> | 675 | template <typename T> |
| 659 | bool WriteExclusive(const VAddr vaddr, const T data, const T expected) { | 676 | bool WriteExclusive(VAddr vaddr, const T data, const T expected) { |
| 677 | // AARCH64 masks the upper 16 bit of all memory accesses | ||
| 678 | vaddr &= 0xffffffffffffLL; | ||
| 679 | |||
| 680 | if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { | ||
| 681 | LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, | ||
| 682 | static_cast<u32>(data), vaddr); | ||
| 683 | return true; | ||
| 684 | } | ||
| 685 | |||
| 660 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); | 686 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); |
| 661 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { | 687 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { |
| 662 | // NOTE: Avoid adding any extra logic to this fast-path block | 688 | // NOTE: Avoid adding any extra logic to this fast-path block |
| @@ -683,7 +709,16 @@ struct Memory::Impl { | |||
| 683 | return true; | 709 | return true; |
| 684 | } | 710 | } |
| 685 | 711 | ||
| 686 | bool WriteExclusive128(const VAddr vaddr, const u128 data, const u128 expected) { | 712 | bool WriteExclusive128(VAddr vaddr, const u128 data, const u128 expected) { |
| 713 | // AARCH64 masks the upper 16 bit of all memory accesses | ||
| 714 | vaddr &= 0xffffffffffffLL; | ||
| 715 | |||
| 716 | if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { | ||
| 717 | LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, | ||
| 718 | static_cast<u32>(data[0]), vaddr); | ||
| 719 | return true; | ||
| 720 | } | ||
| 721 | |||
| 687 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); | 722 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); |
| 688 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { | 723 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { |
| 689 | // NOTE: Avoid adding any extra logic to this fast-path block | 724 | // NOTE: Avoid adding any extra logic to this fast-path block |