aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/include/arch/memory/paging.hpp26
-rw-r--r--arch/x86_64/src/boot/boot.s6
-rw-r--r--arch/x86_64/src/memory/paging.cpp27
3 files changed, 56 insertions, 3 deletions
diff --git a/arch/x86_64/include/arch/memory/paging.hpp b/arch/x86_64/include/arch/memory/paging.hpp
index 16fa476..7b705ac 100644
--- a/arch/x86_64/include/arch/memory/paging.hpp
+++ b/arch/x86_64/include/arch/memory/paging.hpp
@@ -91,6 +91,9 @@ namespace teachos::arch::memory
*/
auto contains_flags(std::bitset<64U> other) const -> bool;
+ std::bitset<64U> flags; ///< Underlying bitset used to read the flags from. Bits 9 - 11 and 52 - 62 can be freely
+ ///< used for additional flags by the operating system.
+
private:
/**
* @brief Extracts the physical address from the underlying bitset read from bit index 12 - 51. Is a 52 bit page
@@ -100,9 +103,6 @@ namespace teachos::arch::memory
* @return Extracted physical address of the next page or of the frame for P1 page tables.
*/
auto calculate_physical_address() const -> std::size_t;
-
- std::bitset<64U> flags; ///< Underlying bitset used to read the flags from. Bits 9 - 11 and 52 - 62 can be freely
- ///< used for additional flags by the operating system.
};
/**
@@ -116,6 +116,25 @@ namespace teachos::arch::memory
auto zero_entries() -> void;
/**
+ * @brief Find and return the next table address
+ *
+ * The next table address is only valid if the corresponding entry is present
+ * and does not create a huge page
+ *
+ * @param index
+ * @return An optional of the address of the next page table or null
+ */
+ auto next_table_address(std::size_t index) const -> std::optional<std::size_t>;
+
+ /**
+ * @brief Convert the address of a page_table into a page_table
+ *
+ * @param index
+ * @return An optional of the next page table or null
+ */
+ auto next_table(size_t index) const -> std::optional<const page_table *>;
+
+ /**
* @brief Index operator overload to access specific entries directy
*
* @param index
@@ -129,6 +148,7 @@ namespace teachos::arch::memory
private:
entry entries[PAGE_TABLE_ENTRY_COUNT];
+ page_table const * p4 = reinterpret_cast<page_table *>(0xfffffffffffff000);
};
} // namespace teachos::arch::memory
diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s
index 0c21c66..29ac58d 100644
--- a/arch/x86_64/src/boot/boot.s
+++ b/arch/x86_64/src/boot/boot.s
@@ -264,6 +264,12 @@ enable_paging:
mov $page_map_level_4, %eax
mov %eax, %cr3
+ /* Map the P4 table recursively */
+ mov $page_map_level_4, %eax
+ or 0b11, %eax
+ // TODO: WHY THIS THROW ERROR?
+ mov %eax, [$page_map_level_4 + 511 * 8]
+
/* Enable Physical Address Extension */
mov %cr4, %eax
or $(1 << 5), %eax
diff --git a/arch/x86_64/src/memory/paging.cpp b/arch/x86_64/src/memory/paging.cpp
index 445c796..61d9d0f 100644
--- a/arch/x86_64/src/memory/paging.cpp
+++ b/arch/x86_64/src/memory/paging.cpp
@@ -50,4 +50,31 @@ namespace teachos::arch::memory
entry->set_unused();
}
}
+
+ auto page_table::next_table_address(std::size_t index) const -> std::optional<std::size_t>
+ {
+ auto entry = entries[index];
+
+ if (entry.contains_flags(entry.PRESENT) && !entry.contains_flags(entry.HUGE_PAGE))
+ {
+ std::size_t table_address = reinterpret_cast<std::size_t>(this);
+ return (table_address << 9) | (index << 12);
+ }
+ else
+ {
+ return std::nullopt;
+ }
+ }
+
+ auto page_table::next_table(size_t index) const -> std::optional<const page_table *>
+ {
+ auto address = next_table_address(index);
+
+ if (address.has_value())
+ {
+ return reinterpret_cast<const page_table *>(*address);
+ }
+
+ return std::nullopt;
+ }
} // namespace teachos::arch::memory