forked from suyu/suyu
common: page_table: Update to use VirtualBuffer and simplify.
This commit is contained in:
parent
1d5923e150
commit
4c1812ae37
2 changed files with 18 additions and 53 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue