summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/page_table.cpp58
-rw-r--r--src/common/page_table.h24
2 files changed, 76 insertions, 6 deletions
diff --git a/src/common/page_table.cpp b/src/common/page_table.cpp
index 9fffd816f..4817b09f9 100644
--- a/src/common/page_table.cpp
+++ b/src/common/page_table.cpp
@@ -10,11 +10,65 @@ PageTable::PageTable() = default;
10 10
11PageTable::~PageTable() noexcept = default; 11PageTable::~PageTable() noexcept = default;
12 12
13void PageTable::Resize(size_t address_space_width_in_bits, size_t page_size_in_bits) { 13bool PageTable::BeginTraversal(TraversalEntry& out_entry, TraversalContext& out_context,
14 const size_t num_page_table_entries{1ULL << (address_space_width_in_bits - page_size_in_bits)}; 14 u64 address) const {
15 // Setup invalid defaults.
16 out_entry.phys_addr = 0;
17 out_entry.block_size = page_size;
18 out_context.next_page = 0;
19
20 // Validate that we can read the actual entry.
21 const auto page = address / page_size;
22 if (page >= backing_addr.size()) {
23 return false;
24 }
25
26 // Validate that the entry is mapped.
27 const auto phys_addr = backing_addr[page];
28 if (phys_addr == 0) {
29 return false;
30 }
31
32 // Populate the results.
33 out_entry.phys_addr = phys_addr + address;
34 out_context.next_page = page + 1;
35 out_context.next_offset = address + page_size;
36
37 return true;
38}
39
40bool PageTable::ContinueTraversal(TraversalEntry& out_entry, TraversalContext& context) const {
41 // Setup invalid defaults.
42 out_entry.phys_addr = 0;
43 out_entry.block_size = page_size;
44
45 // Validate that we can read the actual entry.
46 const auto page = context.next_page;
47 if (page >= backing_addr.size()) {
48 return false;
49 }
50
51 // Validate that the entry is mapped.
52 const auto phys_addr = backing_addr[page];
53 if (phys_addr == 0) {
54 return false;
55 }
56
57 // Populate the results.
58 out_entry.phys_addr = phys_addr + context.next_offset;
59 context.next_page = page + 1;
60 context.next_offset += page_size;
61
62 return true;
63}
64
65void PageTable::Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits) {
66 const std::size_t num_page_table_entries{1ULL
67 << (address_space_width_in_bits - page_size_in_bits)};
15 pointers.resize(num_page_table_entries); 68 pointers.resize(num_page_table_entries);
16 backing_addr.resize(num_page_table_entries); 69 backing_addr.resize(num_page_table_entries);
17 current_address_space_width_in_bits = address_space_width_in_bits; 70 current_address_space_width_in_bits = address_space_width_in_bits;
71 page_size = 1ULL << page_size_in_bits;
18} 72}
19 73
20} // namespace Common 74} // namespace Common
diff --git a/src/common/page_table.h b/src/common/page_table.h
index 8267e8b4d..82d91e9f3 100644
--- a/src/common/page_table.h
+++ b/src/common/page_table.h
@@ -27,6 +27,16 @@ enum class PageType : u8 {
27 * mimics the way a real CPU page table works. 27 * mimics the way a real CPU page table works.
28 */ 28 */
29struct PageTable { 29struct PageTable {
30 struct TraversalEntry {
31 u64 phys_addr{};
32 std::size_t block_size{};
33 };
34
35 struct TraversalContext {
36 u64 next_page{};
37 u64 next_offset{};
38 };
39
30 /// Number of bits reserved for attribute tagging. 40 /// Number of bits reserved for attribute tagging.
31 /// This can be at most the guaranteed alignment of the pointers in the page table. 41 /// This can be at most the guaranteed alignment of the pointers in the page table.
32 static constexpr int ATTRIBUTE_BITS = 2; 42 static constexpr int ATTRIBUTE_BITS = 2;
@@ -89,6 +99,10 @@ struct PageTable {
89 PageTable(PageTable&&) noexcept = default; 99 PageTable(PageTable&&) noexcept = default;
90 PageTable& operator=(PageTable&&) noexcept = default; 100 PageTable& operator=(PageTable&&) noexcept = default;
91 101
102 bool BeginTraversal(TraversalEntry& out_entry, TraversalContext& out_context,
103 u64 address) const;
104 bool ContinueTraversal(TraversalEntry& out_entry, TraversalContext& context) const;
105
92 /** 106 /**
93 * Resizes the page table to be able to accommodate enough pages within 107 * Resizes the page table to be able to accommodate enough pages within
94 * a given address space. 108 * a given address space.
@@ -96,9 +110,9 @@ struct PageTable {
96 * @param address_space_width_in_bits The address size width in bits. 110 * @param address_space_width_in_bits The address size width in bits.
97 * @param page_size_in_bits The page size in bits. 111 * @param page_size_in_bits The page size in bits.
98 */ 112 */
99 void Resize(size_t address_space_width_in_bits, size_t page_size_in_bits); 113 void Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits);
100 114
101 size_t GetAddressSpaceBits() const { 115 std::size_t GetAddressSpaceBits() const {
102 return current_address_space_width_in_bits; 116 return current_address_space_width_in_bits;
103 } 117 }
104 118
@@ -110,9 +124,11 @@ struct PageTable {
110 124
111 VirtualBuffer<u64> backing_addr; 125 VirtualBuffer<u64> backing_addr;
112 126
113 size_t current_address_space_width_in_bits; 127 std::size_t current_address_space_width_in_bits{};
128
129 u8* fastmem_arena{};
114 130
115 u8* fastmem_arena; 131 std::size_t page_size{};
116}; 132};
117 133
118} // namespace Common 134} // namespace Common