summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/page_table.cpp34
-rw-r--r--src/common/page_table.h37
2 files changed, 18 insertions, 53 deletions
diff --git a/src/common/page_table.cpp b/src/common/page_table.cpp
index 566b57b62..e5d3090d5 100644
--- a/src/common/page_table.cpp
+++ b/src/common/page_table.cpp
@@ -6,36 +6,20 @@
6 6
7namespace Common { 7namespace Common {
8 8
9PageTable::PageTable(std::size_t page_size_in_bits) : page_size_in_bits{page_size_in_bits} {} 9PageTable::PageTable() = default;
10 10
11PageTable::~PageTable() = default; 11PageTable::~PageTable() = default;
12 12
13void PageTable::Resize(std::size_t address_space_width_in_bits) { 13void PageTable::Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits,
14 const std::size_t num_page_table_entries = 1ULL 14 bool has_attribute) {
15 << (address_space_width_in_bits - page_size_in_bits); 15 const std::size_t num_page_table_entries{1ULL
16 16 << (address_space_width_in_bits - page_size_in_bits)};
17 pointers.resize(num_page_table_entries); 17 pointers.resize(num_page_table_entries);
18 attributes.resize(num_page_table_entries);
19
20 // The default is a 39-bit address space, which causes an initial 1GB allocation size. If the
21 // vector size is subsequently decreased (via resize), the vector might not automatically
22 // actually reallocate/resize its underlying allocation, which wastes up to ~800 MB for
23 // 36-bit titles. Call shrink_to_fit to reduce capacity to what's actually in use.
24
25 pointers.shrink_to_fit();
26 attributes.shrink_to_fit();
27}
28
29BackingPageTable::BackingPageTable(std::size_t page_size_in_bits) : PageTable{page_size_in_bits} {}
30
31BackingPageTable::~BackingPageTable() = default;
32
33void BackingPageTable::Resize(std::size_t address_space_width_in_bits) {
34 PageTable::Resize(address_space_width_in_bits);
35 const std::size_t num_page_table_entries = 1ULL
36 << (address_space_width_in_bits - page_size_in_bits);
37 backing_addr.resize(num_page_table_entries); 18 backing_addr.resize(num_page_table_entries);
38 backing_addr.shrink_to_fit(); 19
20 if (has_attribute) {
21 attributes.resize(num_page_table_entries);
22 }
39} 23}
40 24
41} // namespace Common 25} // namespace Common
diff --git a/src/common/page_table.h b/src/common/page_table.h
index dbc272ab7..1e8bd3187 100644
--- a/src/common/page_table.h
+++ b/src/common/page_table.h
@@ -5,9 +5,12 @@
5#pragma once 5#pragma once
6 6
7#include <vector> 7#include <vector>
8
8#include <boost/icl/interval_map.hpp> 9#include <boost/icl/interval_map.hpp>
10
9#include "common/common_types.h" 11#include "common/common_types.h"
10#include "common/memory_hook.h" 12#include "common/memory_hook.h"
13#include "common/virtual_buffer.h"
11 14
12namespace Common { 15namespace Common {
13 16
@@ -47,7 +50,7 @@ struct SpecialRegion {
47 * mimics the way a real CPU page table works. 50 * mimics the way a real CPU page table works.
48 */ 51 */
49struct PageTable { 52struct PageTable {
50 explicit PageTable(std::size_t page_size_in_bits); 53 PageTable();
51 ~PageTable(); 54 ~PageTable();
52 55
53 /** 56 /**
@@ -56,40 +59,18 @@ struct PageTable {
56 * 59 *
57 * @param address_space_width_in_bits The address size width in bits. 60 * @param address_space_width_in_bits The address size width in bits.
58 */ 61 */
59 void Resize(std::size_t address_space_width_in_bits); 62 void Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits,
63 bool has_attribute);
60 64
61 /** 65 /**
62 * Vector of memory pointers backing each page. An entry can only be non-null if the 66 * Vector of memory pointers backing each page. An entry can only be non-null if the
63 * corresponding entry in the `attributes` vector is of type `Memory`. 67 * corresponding entry in the `attributes` vector is of type `Memory`.
64 */ 68 */
65 std::vector<u8*> pointers; 69 VirtualBuffer<u8*> pointers;
66
67 /**
68 * Contains MMIO handlers that back memory regions whose entries in the `attribute` vector is
69 * of type `Special`.
70 */
71 boost::icl::interval_map<u64, std::set<SpecialRegion>> special_regions;
72
73 /**
74 * Vector of fine grained page attributes. If it is set to any value other than `Memory`, then
75 * the corresponding entry in `pointers` MUST be set to null.
76 */
77 std::vector<PageType> attributes;
78
79 const std::size_t page_size_in_bits{};
80};
81
82/**
83 * A more advanced Page Table with the ability to save a backing address when using it
84 * depends on another MMU.
85 */
86struct BackingPageTable : PageTable {
87 explicit BackingPageTable(std::size_t page_size_in_bits);
88 ~BackingPageTable();
89 70
90 void Resize(std::size_t address_space_width_in_bits); 71 VirtualBuffer<u64> backing_addr;
91 72
92 std::vector<u64> backing_addr; 73 VirtualBuffer<PageType> attributes;
93}; 74};
94 75
95} // namespace Common 76} // namespace Common