common: page_table: Update to use VirtualBuffer and simplify.

This commit is contained in:
bunnei 2020-04-08 22:49:51 -04:00
parent 1d5923e150
commit 4c1812ae37
2 changed files with 18 additions and 53 deletions

View file

@ -6,36 +6,20 @@
namespace Common { 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; PageTable::~PageTable() = default;
void PageTable::Resize(std::size_t address_space_width_in_bits) { void PageTable::Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits,
const std::size_t num_page_table_entries = 1ULL bool has_attribute) {
<< (address_space_width_in_bits - page_size_in_bits); const std::size_t num_page_table_entries{1ULL
<< (address_space_width_in_bits - page_size_in_bits)};
pointers.resize(num_page_table_entries); 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.resize(num_page_table_entries);
backing_addr.shrink_to_fit();
if (has_attribute) {
attributes.resize(num_page_table_entries);
}
} }
} // namespace Common } // namespace Common

View file

@ -5,9 +5,12 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include <boost/icl/interval_map.hpp> #include <boost/icl/interval_map.hpp>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/memory_hook.h" #include "common/memory_hook.h"
#include "common/virtual_buffer.h"
namespace Common { namespace Common {
@ -47,7 +50,7 @@ struct SpecialRegion {
* mimics the way a real CPU page table works. * mimics the way a real CPU page table works.
*/ */
struct PageTable { struct PageTable {
explicit PageTable(std::size_t page_size_in_bits); PageTable();
~PageTable(); ~PageTable();
/** /**
@ -56,40 +59,18 @@ struct PageTable {
* *
* @param address_space_width_in_bits The address size width in bits. * @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 * 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 entry in the `attributes` vector is of type `Memory`.
*/ */
std::vector<u8*> pointers; VirtualBuffer<u8*> pointers;
/** VirtualBuffer<u64> backing_addr;
* 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<PageType> attributes;
* 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;
}; };
} // namespace Common } // namespace Common