From 0890451c554973b907dc8febe6e65b499f21ab09 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 17 Nov 2020 19:43:24 -0500 Subject: page_table: Remove unnecessary header inclusions Prevents indirect inclusions for these headers. --- src/common/page_table.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/common/page_table.h') diff --git a/src/common/page_table.h b/src/common/page_table.h index cf5eed780..9908947ac 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h @@ -4,10 +4,6 @@ #pragma once -#include - -#include - #include "common/common_types.h" #include "common/memory_hook.h" #include "common/virtual_buffer.h" -- cgit v1.2.3 From 3cfd962ef471fa064f0f72eceff2a592e37b6642 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 17 Nov 2020 19:45:17 -0500 Subject: page_table: Add missing doxygen parameters to Resize() Resolves two -Wdocumentation warnings. --- src/common/page_table.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/common/page_table.h') diff --git a/src/common/page_table.h b/src/common/page_table.h index 9908947ac..a5be7a668 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h @@ -54,6 +54,8 @@ struct PageTable { * a given address space. * * @param address_space_width_in_bits The address size width in bits. + * @param page_size_in_bits The page size in bits. + * @param has_attribute Whether or not this page has any backing attributes. */ void Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits, bool has_attribute); -- cgit v1.2.3 From b3c8997829ed986c948d195bc1e7c8f66c42755e Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 17 Nov 2020 19:58:41 -0500 Subject: page_table: Allow page tables to be moved Makes page tables and virtual buffers able to be moved, but not copied, making the interface more flexible. Previously, with the destructor specified, but no move assignment or constructor specified, they wouldn't be implicitly generated. --- src/common/page_table.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/common/page_table.h') diff --git a/src/common/page_table.h b/src/common/page_table.h index a5be7a668..9754fabf9 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h @@ -4,6 +4,8 @@ #pragma once +#include + #include "common/common_types.h" #include "common/memory_hook.h" #include "common/virtual_buffer.h" @@ -47,7 +49,13 @@ struct SpecialRegion { */ struct PageTable { PageTable(); - ~PageTable(); + ~PageTable() noexcept; + + PageTable(const PageTable&) = delete; + PageTable& operator=(const PageTable&) = delete; + + PageTable(PageTable&&) noexcept = default; + PageTable& operator=(PageTable&&) noexcept = default; /** * Resizes the page table to be able to accomodate enough pages within -- cgit v1.2.3 From b3587102d160fb74a12935a79f06ee8a12712f12 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 29 Dec 2020 21:16:57 -0300 Subject: core/memory: Read and write page table atomically Squash attributes into the pointer's integer, making them an uintptr_t pair containing 2 bits at the bottom and then the pointer. These bits are currently unused thanks to alignment requirements. Configure Dynarmic to mask out these bits on pointer reads. While we are at it, remove some unused attributes carried over from Citra. Read/Write and other hot functions use a two step unpacking process that is less readable to stop MSVC from emitting an extra AND instruction in the hot path: mov rdi,rcx shr rdx,0Ch mov r8,qword ptr [rax+8] mov rax,qword ptr [r8+rdx*8] mov rdx,rax -and al,3 and rdx,0FFFFFFFFFFFFFFFCh je Core::Memory::Memory::Impl::Read mov rax,qword ptr [vaddr] movzx eax,byte ptr [rdx+rax] --- src/common/page_table.h | 68 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 11 deletions(-) (limited to 'src/common/page_table.h') diff --git a/src/common/page_table.h b/src/common/page_table.h index 9754fabf9..8d4ee9249 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include "common/common_types.h" @@ -20,10 +21,6 @@ enum class PageType : u8 { /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and /// invalidation RasterizerCachedMemory, - /// Page is mapped to a I/O region. Writing and reading to this page is handled by functions. - Special, - /// Page is allocated for use. - Allocated, }; struct SpecialRegion { @@ -48,6 +45,59 @@ struct SpecialRegion { * mimics the way a real CPU page table works. */ struct PageTable { + /// Number of bits reserved for attribute tagging. + /// This can be at most the guaranteed alignment of the pointers in the page table. + static constexpr int ATTRIBUTE_BITS = 2; + + /** + * Pair of host pointer and page type attribute. + * This uses the lower bits of a given pointer to store the attribute tag. + * Writing and reading the pointer attribute pair is guaranteed to be atomic for the same method + * call. In other words, they are guaranteed to be synchronized at all times. + */ + class PageInfo { + public: + /// Returns the page pointer + [[nodiscard]] u8* Pointer() const noexcept { + return ExtractPointer(raw.load(std::memory_order_relaxed)); + } + + /// Returns the page type attribute + [[nodiscard]] PageType Type() const noexcept { + return ExtractType(raw.load(std::memory_order_relaxed)); + } + + /// Returns the page pointer and attribute pair, extracted from the same atomic read + [[nodiscard]] std::pair PointerType() const noexcept { + const uintptr_t non_atomic_raw = raw.load(std::memory_order_relaxed); + return {ExtractPointer(non_atomic_raw), ExtractType(non_atomic_raw)}; + } + + /// Returns the raw representation of the page information. + /// Use ExtractPointer and ExtractType to unpack the value. + [[nodiscard]] uintptr_t Raw() const noexcept { + return raw.load(std::memory_order_relaxed); + } + + /// Write a page pointer and type pair atomically + void Store(u8* pointer, PageType type) noexcept { + raw.store(reinterpret_cast(pointer) | static_cast(type)); + } + + /// Unpack a pointer from a page info raw representation + [[nodiscard]] static u8* ExtractPointer(uintptr_t raw) noexcept { + return reinterpret_cast(raw & (~uintptr_t{0} << ATTRIBUTE_BITS)); + } + + /// Unpack a page type from a page info raw representation + [[nodiscard]] static PageType ExtractType(uintptr_t raw) noexcept { + return static_cast(raw & ((uintptr_t{1} << ATTRIBUTE_BITS) - 1)); + } + + private: + std::atomic raw; + }; + PageTable(); ~PageTable() noexcept; @@ -63,20 +113,16 @@ struct PageTable { * * @param address_space_width_in_bits The address size width in bits. * @param page_size_in_bits The page size in bits. - * @param has_attribute Whether or not this page has any backing attributes. */ - void Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits, - bool has_attribute); + void Resize(size_t address_space_width_in_bits, size_t page_size_in_bits); /** * Vector of memory pointers backing each page. An entry can only be non-null if the - * corresponding entry in the `attributes` vector is of type `Memory`. + * corresponding attribute element is of type `Memory`. */ - VirtualBuffer pointers; + VirtualBuffer pointers; VirtualBuffer backing_addr; - - VirtualBuffer attributes; }; } // namespace Common -- cgit v1.2.3 From 6d30745d772c7e332bbea1462a92033386b85b08 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Fri, 1 Jan 2021 11:30:30 +0000 Subject: memory: Remove MemoryHook --- src/common/page_table.h | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'src/common/page_table.h') diff --git a/src/common/page_table.h b/src/common/page_table.h index 8d4ee9249..0c14e6433 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h @@ -8,7 +8,6 @@ #include #include "common/common_types.h" -#include "common/memory_hook.h" #include "common/virtual_buffer.h" namespace Common { @@ -23,23 +22,6 @@ enum class PageType : u8 { RasterizerCachedMemory, }; -struct SpecialRegion { - enum class Type { - DebugHook, - IODevice, - } type; - - MemoryHookPointer handler; - - [[nodiscard]] bool operator<(const SpecialRegion& other) const { - return std::tie(type, handler) < std::tie(other.type, other.handler); - } - - [[nodiscard]] bool operator==(const SpecialRegion& other) const { - return std::tie(type, handler) == std::tie(other.type, other.handler); - } -}; - /** * A (reasonably) fast way of allowing switchable and remappable process address spaces. It loosely * mimics the way a real CPU page table works. -- cgit v1.2.3 From a745d87971b2c9795e1b2c587bfe30b849b522fa Mon Sep 17 00:00:00 2001 From: Morph Date: Sat, 2 Jan 2021 09:00:05 -0500 Subject: general: Fix various spelling errors --- src/common/page_table.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/common/page_table.h') diff --git a/src/common/page_table.h b/src/common/page_table.h index 0c14e6433..61c5552e0 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h @@ -90,7 +90,7 @@ struct PageTable { PageTable& operator=(PageTable&&) noexcept = default; /** - * Resizes the page table to be able to accomodate enough pages within + * Resizes the page table to be able to accommodate enough pages within * a given address space. * * @param address_space_width_in_bits The address size width in bits. -- cgit v1.2.3