common: page_table: Update to use VirtualBuffer and simplify.
This commit is contained in:
		| @@ -6,36 +6,20 @@ | ||||
|  | ||||
| namespace Common { | ||||
|  | ||||
| PageTable::PageTable(std::size_t page_size_in_bits) : page_size_in_bits{page_size_in_bits} {} | ||||
| PageTable::PageTable() = default; | ||||
|  | ||||
| PageTable::~PageTable() = default; | ||||
|  | ||||
| void PageTable::Resize(std::size_t address_space_width_in_bits) { | ||||
|     const std::size_t num_page_table_entries = 1ULL | ||||
|                                                << (address_space_width_in_bits - page_size_in_bits); | ||||
|  | ||||
| void PageTable::Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits, | ||||
|                        bool has_attribute) { | ||||
|     const std::size_t num_page_table_entries{1ULL | ||||
|                                              << (address_space_width_in_bits - page_size_in_bits)}; | ||||
|     pointers.resize(num_page_table_entries); | ||||
|     attributes.resize(num_page_table_entries); | ||||
|  | ||||
|     // The default is a 39-bit address space, which causes an initial 1GB allocation size. If the | ||||
|     // vector size is subsequently decreased (via resize), the vector might not automatically | ||||
|     // actually reallocate/resize its underlying allocation, which wastes up to ~800 MB for | ||||
|     // 36-bit titles. Call shrink_to_fit to reduce capacity to what's actually in use. | ||||
|  | ||||
|     pointers.shrink_to_fit(); | ||||
|     attributes.shrink_to_fit(); | ||||
| } | ||||
|  | ||||
| BackingPageTable::BackingPageTable(std::size_t page_size_in_bits) : PageTable{page_size_in_bits} {} | ||||
|  | ||||
| BackingPageTable::~BackingPageTable() = default; | ||||
|  | ||||
| void BackingPageTable::Resize(std::size_t address_space_width_in_bits) { | ||||
|     PageTable::Resize(address_space_width_in_bits); | ||||
|     const std::size_t num_page_table_entries = 1ULL | ||||
|                                                << (address_space_width_in_bits - page_size_in_bits); | ||||
|     backing_addr.resize(num_page_table_entries); | ||||
|     backing_addr.shrink_to_fit(); | ||||
|  | ||||
|     if (has_attribute) { | ||||
|         attributes.resize(num_page_table_entries); | ||||
|     } | ||||
| } | ||||
|  | ||||
| } // namespace Common | ||||
|   | ||||
| @@ -5,9 +5,12 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| #include <boost/icl/interval_map.hpp> | ||||
|  | ||||
| #include "common/common_types.h" | ||||
| #include "common/memory_hook.h" | ||||
| #include "common/virtual_buffer.h" | ||||
|  | ||||
| namespace Common { | ||||
|  | ||||
| @@ -47,7 +50,7 @@ struct SpecialRegion { | ||||
|  * mimics the way a real CPU page table works. | ||||
|  */ | ||||
| struct PageTable { | ||||
|     explicit PageTable(std::size_t page_size_in_bits); | ||||
|     PageTable(); | ||||
|     ~PageTable(); | ||||
|  | ||||
|     /** | ||||
| @@ -56,40 +59,18 @@ struct PageTable { | ||||
|      * | ||||
|      * @param address_space_width_in_bits The address size width in bits. | ||||
|      */ | ||||
|     void Resize(std::size_t address_space_width_in_bits); | ||||
|     void Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits, | ||||
|                 bool has_attribute); | ||||
|  | ||||
|     /** | ||||
|      * 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`. | ||||
|      */ | ||||
|     std::vector<u8*> pointers; | ||||
|     VirtualBuffer<u8*> pointers; | ||||
|  | ||||
|     /** | ||||
|      * Contains MMIO handlers that back memory regions whose entries in the `attribute` vector is | ||||
|      * of type `Special`. | ||||
|      */ | ||||
|     boost::icl::interval_map<u64, std::set<SpecialRegion>> special_regions; | ||||
|     VirtualBuffer<u64> backing_addr; | ||||
|  | ||||
|     /** | ||||
|      * Vector of fine grained page attributes. If it is set to any value other than `Memory`, then | ||||
|      * the corresponding entry in `pointers` MUST be set to null. | ||||
|      */ | ||||
|     std::vector<PageType> attributes; | ||||
|  | ||||
|     const std::size_t page_size_in_bits{}; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * A more advanced Page Table with the ability to save a backing address when using it | ||||
|  * depends on another MMU. | ||||
|  */ | ||||
| struct BackingPageTable : PageTable { | ||||
|     explicit BackingPageTable(std::size_t page_size_in_bits); | ||||
|     ~BackingPageTable(); | ||||
|  | ||||
|     void Resize(std::size_t address_space_width_in_bits); | ||||
|  | ||||
|     std::vector<u64> backing_addr; | ||||
|     VirtualBuffer<PageType> attributes; | ||||
| }; | ||||
|  | ||||
| } // namespace Common | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 bunnei
					bunnei