aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/memory
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2024-11-24 09:17:53 +0000
committerMatteo Gmür <matteo.gmuer1@ost.ch>2024-11-24 09:17:53 +0000
commit4c44f822eefa743649693e0a49a978291925ddff (patch)
tree5a7aa6b9023ae4c52eba059f28bec40f8d0eb855 /arch/x86_64/src/memory
parent27a56b0e828cecaa5a6a40e3f30b5c0e1785aff6 (diff)
downloadteachos-4c44f822eefa743649693e0a49a978291925ddff.tar.xz
teachos-4c44f822eefa743649693e0a49a978291925ddff.zip
Revert: de-templatize paging implementation
Diffstat (limited to 'arch/x86_64/src/memory')
-rw-r--r--arch/x86_64/src/memory/allocator/tiny_frame_allocator.cpp16
-rw-r--r--arch/x86_64/src/memory/paging/active_page_table.cpp67
-rw-r--r--arch/x86_64/src/memory/paging/kernel_mapper.cpp94
-rw-r--r--arch/x86_64/src/memory/paging/page_table.cpp21
-rw-r--r--arch/x86_64/src/memory/paging/temporary_page.cpp9
5 files changed, 1 insertions, 206 deletions
diff --git a/arch/x86_64/src/memory/allocator/tiny_frame_allocator.cpp b/arch/x86_64/src/memory/allocator/tiny_frame_allocator.cpp
index ed000a0..3cdf9c7 100644
--- a/arch/x86_64/src/memory/allocator/tiny_frame_allocator.cpp
+++ b/arch/x86_64/src/memory/allocator/tiny_frame_allocator.cpp
@@ -4,22 +4,6 @@
namespace teachos::arch::memory::allocator
{
- tiny_frame_allocator::tiny_frame_allocator(frame_allocator & allocator)
- : frames{}
- {
- // Has to be done this way, because constructing the constructor with the data from allocator.allocate_frames(),
- // does not work because it would set the value correctly but because we pass it as an std::optional it would not
- // set the engaged flag. Meaning the has_value() method would still return false.
- for (auto & frame : frames)
- {
- auto allocated = allocator.allocate_frame();
- if (allocated.has_value())
- {
- frame.emplace(allocated.value());
- }
- }
- }
-
auto tiny_frame_allocator::allocate_frame() -> std::optional<physical_frame>
{
for (auto & frame_option : frames)
diff --git a/arch/x86_64/src/memory/paging/active_page_table.cpp b/arch/x86_64/src/memory/paging/active_page_table.cpp
index d2bf683..0113869 100644
--- a/arch/x86_64/src/memory/paging/active_page_table.cpp
+++ b/arch/x86_64/src/memory/paging/active_page_table.cpp
@@ -1,7 +1,5 @@
#include "arch/memory/paging/active_page_table.hpp"
-#include "arch/memory/cpu/tlb.hpp"
-
namespace teachos::arch::memory::paging
{
namespace
@@ -17,71 +15,6 @@ namespace teachos::arch::memory::paging
return active_page;
}
- auto active_page_table::map_page_to_frame(allocator::frame_allocator & allocator, virtual_page page,
- allocator::physical_frame frame, std::bitset<64U> flags) -> void
- {
- auto current_handle = active_handle;
-
- for (auto level = page_table_handle::LEVEL4; level != page_table_handle::LEVEL1; --level)
- {
- current_handle = current_handle.next_table_or_create(allocator, page.get_level_index(level));
- }
-
- auto & level1_entry = current_handle[page.get_level_index(page_table_handle::LEVEL1)];
- arch::exception_handling::assert(!level1_entry.contains_flags(entry::HUGE_PAGE),
- "[Page Mapper] Unable to map huge pages");
- arch::exception_handling::assert(level1_entry.is_unused(), "[Page Mapper] Page table entry is already used");
- level1_entry.set_entry(frame, flags.to_ulong() | entry::PRESENT);
- }
-
- auto active_page_table::identity_map(allocator::frame_allocator & allocator, allocator::physical_frame frame,
- std::bitset<64U> flags) -> void
- {
- auto const page = virtual_page::containing_address(frame.start_address());
- map_page_to_frame(allocator, page, frame, flags);
- }
-
- auto active_page_table::map_next_free_page_to_frame(allocator::frame_allocator & allocator, virtual_page page,
- std::bitset<64U> flags) -> void
- {
- auto const frame = allocator.allocate_frame();
- exception_handling::assert(frame.has_value(), "[Page mapper] Out of memory exception");
- map_page_to_frame(allocator, page, frame.value(), flags);
- }
-
- auto active_page_table::unmap_page(allocator::frame_allocator & allocator, virtual_page page) -> void
- {
- exception_handling::assert(translate_page(page).has_value(),
- "[Page Mapper] Attempted to unmap page, which has not been mapped previously");
-
- auto current_handle = active_handle;
-
- for (auto level = page_table_handle::LEVEL4; level != page_table_handle::LEVEL1; --level)
- {
- auto const level_index = page.get_level_index(level);
- auto const next_handle = current_handle.next_table(level_index);
- // The next table method failed even tough the page has to be mapped already, because translate_page did not
- // fail. This can only mean that we attempted to unmap a huge page, which is not supported in the first place.
- exception_handling::assert(next_handle.has_value(), "[Page Mapper] Unable to unmap huge pages");
- current_handle = next_handle.value();
- }
-
- unmap_page_table_entry(allocator, page, current_handle);
- cpu::tlb_flush(page.start_address());
- }
-
- auto active_page_table::unmap_page_table_entry(allocator::frame_allocator & allocator, virtual_page page,
- page_table_handle & handle) -> void
- {
- auto level_index = page.get_level_index(handle.get_level());
- auto & entry = handle[level_index];
- auto const frame = entry.calculate_pointed_to_frame();
- exception_handling::assert(frame.has_value(),
- "[Page Mapper] Attempted to unmap page, which has not been mapped previously");
- entry.set_unused();
- allocator.deallocate_frame(frame.value());
- }
-
auto active_page_table::operator[](std::size_t index) -> entry & { return active_handle[index]; }
auto active_page_table::translate_address(virtual_address address) -> std::optional<allocator::physical_address>
diff --git a/arch/x86_64/src/memory/paging/kernel_mapper.cpp b/arch/x86_64/src/memory/paging/kernel_mapper.cpp
deleted file mode 100644
index f938cb3..0000000
--- a/arch/x86_64/src/memory/paging/kernel_mapper.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-#include "arch/memory/paging/kernel_mapper.hpp"
-
-#include "arch/memory/cpu/control_register.hpp"
-#include "arch/memory/cpu/tlb.hpp"
-#include "arch/memory/paging/temporary_page.hpp"
-#include "arch/video/vga/text.hpp"
-
-namespace teachos::arch::memory::paging
-{
-
- kernel_mapper::kernel_mapper(allocator::frame_allocator & allocator, multiboot::memory_information const & mem_info)
- : allocator(allocator)
- , mem_info(mem_info)
- {
- // Nothing to do
- }
-
- auto kernel_mapper::remap_kernel() -> active_page_table &
- {
- temporary_page temporary_page{virtual_page{0xCAFEBABE}, allocator};
- auto & active_table = active_page_table::create_or_get();
- auto const frame = allocator.allocate_frame();
- exception_handling::assert(frame.has_value(),
- "[Kernel Mapper] Frame could not be allocated and therefore kernel not mapped");
- inactive_page_table new_table{frame.value(), active_table, temporary_page};
- remap_elf_kernel_sections(new_table, temporary_page, active_table);
- auto const old_table = switch_active_page_table(new_table);
- auto const old_level_4_page = virtual_page::containing_address(old_table.page_table_level_4_frame.start_address());
- active_table.unmap_page(allocator, old_level_4_page);
- return active_table;
- }
-
- auto kernel_mapper::remap_elf_kernel_sections(inactive_page_table & inactive_table, temporary_page & temporary_page,
- active_page_table & active_table) -> void
- {
- auto const backup =
- allocator::physical_frame::containing_address(cpu::read_control_register(cpu::control_register::CR3));
- auto page_table_level4 = temporary_page.map_table_frame(backup, active_table);
-
- active_table[511].set_entry(inactive_table.page_table_level_4_frame, entry::PRESENT | entry::WRITABLE);
- cpu::tlb_flush_all();
- map_elf_kernel_sections(active_table);
-
- page_table_level4[511].set_entry(backup, entry::PRESENT | entry::WRITABLE);
- cpu::tlb_flush_all();
- temporary_page.unmap_page(active_table);
- }
-
- auto kernel_mapper::switch_active_page_table(inactive_page_table new_table) -> inactive_page_table
- {
- auto const backup =
- allocator::physical_frame::containing_address(cpu::read_control_register(cpu::control_register::CR3));
- auto const old_table = inactive_page_table{backup};
-
- auto const new_address = new_table.page_table_level_4_frame.start_address();
- cpu::write_control_register(cpu::control_register::CR3, new_address);
- return old_table;
- }
-
- auto kernel_mapper::map_elf_kernel_sections(active_page_table & active_table) -> void
- {
- exception_handling::assert(!mem_info.sections.empty(), "[Kernel Mapper] Kernel elf sections empty");
- for (auto const & section : mem_info.sections)
- {
- if (!section.flags.contains_flags(multiboot::elf_section_flags::OCCUPIES_MEMORY))
- {
- continue;
- }
- exception_handling::assert(section.physical_address % allocator::PAGE_FRAME_SIZE == 0U,
- "[Kernel Mapper] Section must be page aligned");
- auto const start_frame = allocator::physical_frame::containing_address(section.physical_address);
- // End address is exclusive, so that it is not part of the section anymore (one past the last frame of this
- // section). But end frame would now point to the actual last frame and not one past the last frame, therefore
- // we increment by one to get one past the last frame of this section.
- auto const end_frame =
- ++(allocator::physical_frame::containing_address(section.physical_address + section.section_size - 1));
-
- allocator::frame_container::iterator const begin{start_frame};
- allocator::frame_container::iterator const end{end_frame};
- allocator::frame_container const frames{begin, end};
- entry const entry{section.flags};
-
- for (auto const & frame : frames)
- {
- active_table.identity_map(allocator, frame, entry.get_flags());
- }
- }
-
- auto const vga_buffer_frame =
- allocator::physical_frame::containing_address(video::vga::text::DEFAULT_VGA_TEXT_BUFFER_ADDRESS);
- active_table.identity_map(allocator, vga_buffer_frame, entry::WRITABLE);
- }
-
-} // namespace teachos::arch::memory::paging \ No newline at end of file
diff --git a/arch/x86_64/src/memory/paging/page_table.cpp b/arch/x86_64/src/memory/paging/page_table.cpp
index 48e6d4f..eb11810 100644
--- a/arch/x86_64/src/memory/paging/page_table.cpp
+++ b/arch/x86_64/src/memory/paging/page_table.cpp
@@ -96,27 +96,6 @@ namespace teachos::arch::memory::paging
"[Page Table] Attempted to pass nullptr as table to page table table method");
}
- auto page_table_handle::next_table_or_create(allocator::frame_allocator & allocator,
- std::size_t table_index) -> page_table_handle
- {
- auto next_handle = next_table(table_index);
- // If the next table method failed then it means that the page level of the frame we want allocate has not yet
- // been created itself. So we have to do that before we are able to allocate the wanted frame. This has to be done
- // for every level, meaning we potenitally create a level 4, level 3 and level 2 page entry, each pointing to a
- // page table one level below.
- if (!next_handle.has_value())
- {
- auto const allocated_frame = allocator.allocate_frame();
- exception_handling::assert(allocated_frame.has_value(), "[Page mapper] Unable to allocate frame");
- this->operator[](table_index).set_entry(allocated_frame.value(), entry::PRESENT | entry::WRITABLE);
- // There should now be an entry at the previously not existent index, therefore we can simply access it again.
- next_handle = next_table(table_index);
- exception_handling::assert(next_handle.has_value(), "[Page mapper] Unable to create new entry into page table");
- next_handle.value().zero_entries();
- }
- return next_handle.value();
- }
-
auto page_table_handle::zero_entries() -> void { table->zero_entries(); }
auto page_table_handle::is_empty() const -> bool { return table->is_empty(); }
diff --git a/arch/x86_64/src/memory/paging/temporary_page.cpp b/arch/x86_64/src/memory/paging/temporary_page.cpp
index 8439864..152241d 100644
--- a/arch/x86_64/src/memory/paging/temporary_page.cpp
+++ b/arch/x86_64/src/memory/paging/temporary_page.cpp
@@ -4,13 +4,6 @@
namespace teachos::arch::memory::paging
{
- temporary_page::temporary_page(virtual_page page, allocator::frame_allocator & allocator)
- : page{page}
- , allocator{allocator}
- {
- // Nothing to do
- }
-
auto temporary_page::map_table_frame(allocator::physical_frame frame,
active_page_table & active_table) -> page_table_handle
{
@@ -31,6 +24,6 @@ namespace teachos::arch::memory::paging
auto temporary_page::unmap_page(active_page_table & active_table) -> void
{
- active_table.unmap_page(this->allocator, page);
+ active_table.unmap_page(allocator, page);
}
} // namespace teachos::arch::memory::paging