diff options
| author | Fabian Imhof <fabian.imhof@ost.ch> | 2024-10-15 15:48:43 +0000 |
|---|---|---|
| committer | Fabian Imhof <fabian.imhof@ost.ch> | 2024-10-15 15:48:43 +0000 |
| commit | 0c4fd9eaed4a71975879aa83cd2da4b6266a64b5 (patch) | |
| tree | 0fb3ef311223e4a9a36ba9fc0fa0e7af1c312596 /arch | |
| parent | 429d99ca40254e9e19da938ff9f2065a543708cd (diff) | |
| download | teachos-0c4fd9eaed4a71975879aa83cd2da4b6266a64b5.tar.xz teachos-0c4fd9eaed4a71975879aa83cd2da4b6266a64b5.zip | |
add 4th level page table
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86_64/include/arch/memory/paging.hpp | 26 | ||||
| -rw-r--r-- | arch/x86_64/src/boot/boot.s | 6 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/paging.cpp | 27 |
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 |
