diff options
Diffstat (limited to 'arch/x86_64/src')
| -rw-r--r-- | arch/x86_64/src/kernel/main.cpp | 4 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/allocator/area_frame_allocator.cpp (renamed from arch/x86_64/src/memory/frame_allocator.cpp) | 21 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/allocator/physical_frame.cpp | 22 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/paging/page_entry.cpp (renamed from arch/x86_64/src/memory/paging.cpp) | 12 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/paging/page_table.cpp | 65 |
5 files changed, 99 insertions, 25 deletions
diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index c0d4aed..09fc2a2 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,7 +1,7 @@ #include "arch/kernel/main.hpp" #include "arch/exception_handling/assert.hpp" -#include "arch/memory/frame_allocator.hpp" +#include "arch/memory/allocator/area_frame_allocator.hpp" #include "arch/memory/multiboot/reader.hpp" #include "arch/video/vga/text.hpp" @@ -18,7 +18,7 @@ namespace teachos::arch::kernel text::write("TeachOS is starting up...", text::common_attributes::green_on_black); auto memory_information = memory::multiboot::read_multiboot2(); - auto allocator = memory::area_frame_allocator(memory_information); + memory::allocator::area_frame_allocator allocator(memory_information); auto last_allocated = allocator.allocate_frame(); auto allocated = last_allocated; diff --git a/arch/x86_64/src/memory/frame_allocator.cpp b/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp index 7776082..9c344d8 100644 --- a/arch/x86_64/src/memory/frame_allocator.cpp +++ b/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp @@ -1,22 +1,9 @@ -#include "arch/memory/frame_allocator.hpp" +#include "arch/memory/allocator/area_frame_allocator.hpp" #include "arch/exception_handling/assert.hpp" -namespace teachos::arch::memory +namespace teachos::arch::memory::allocator { - physical_frame::physical_frame(std::size_t frame_number) - : frame_number(frame_number) - { - // Nothing to do - } - - auto physical_frame::containing_address(std::size_t address) -> physical_frame - { - return physical_frame{address / PAGE_FRAME_SIZE}; - } - - auto physical_frame::start_address() const -> uint64_t { return frame_number * PAGE_FRAME_SIZE; } - area_frame_allocator::area_frame_allocator(multiboot::memory_information mem_info) : next_free_frame(0) , current_area(std::nullopt) @@ -81,7 +68,7 @@ namespace teachos::arch::memory else if (physical_frame >= multiboot_start && physical_frame <= kernel_end) { // `physical_frame` is used by the kernel or multiboot information structure - next_free_frame = arch::memory::physical_frame{kernel_end.frame_number + 1}; + next_free_frame = allocator::physical_frame{kernel_end.frame_number + 1}; } else { @@ -107,4 +94,4 @@ namespace teachos::arch::memory auto area_frame_allocator::begin() -> multiboot::memory_area_iterator { return area_begin; } auto area_frame_allocator::end() -> multiboot::memory_area_iterator { return area_end; } -} // namespace teachos::arch::memory +} // namespace teachos::arch::memory::allocator diff --git a/arch/x86_64/src/memory/allocator/physical_frame.cpp b/arch/x86_64/src/memory/allocator/physical_frame.cpp new file mode 100644 index 0000000..03ec193 --- /dev/null +++ b/arch/x86_64/src/memory/allocator/physical_frame.cpp @@ -0,0 +1,22 @@ +#include "arch/memory/allocator/physical_frame.hpp" + +namespace teachos::arch::memory::allocator +{ + namespace + { + constexpr std::size_t PAGE_FRAME_SIZE = 4096U; ///< Default page size of x86_84 is always 4KiB. + } + + physical_frame::physical_frame(std::size_t frame_number) + : frame_number(frame_number) + { + // Nothing to do + } + + auto physical_frame::containing_address(std::size_t address) -> physical_frame + { + return physical_frame{address / PAGE_FRAME_SIZE}; + } + + auto physical_frame::start_address() const -> uint64_t { return frame_number * PAGE_FRAME_SIZE; } +} // namespace teachos::arch::memory::allocator diff --git a/arch/x86_64/src/memory/paging.cpp b/arch/x86_64/src/memory/paging/page_entry.cpp index 9774132..43c0b71 100644 --- a/arch/x86_64/src/memory/paging.cpp +++ b/arch/x86_64/src/memory/paging/page_entry.cpp @@ -1,19 +1,19 @@ -#include "arch/memory/paging.hpp" +#include "arch/memory/paging/page_entry.hpp" #include "arch/exception_handling/assert.hpp" -namespace teachos::arch::memory +namespace teachos::arch::memory::paging { auto entry::is_unused() const -> bool { return flags == 0U; } auto entry::set_unused() -> void { flags = 0U; } - auto entry::calculate_pointed_to_frame() const -> std::optional<physical_frame> + auto entry::calculate_pointed_to_frame() const -> std::optional<allocator::physical_frame> { if (contains_flags(PRESENT)) { auto physical_address = calculate_physical_address(); - return physical_frame::containing_address(physical_address); + return allocator::physical_frame::containing_address(physical_address); } return std::nullopt; } @@ -33,10 +33,10 @@ namespace teachos::arch::memory auto entry::contains_flags(std::bitset<64U> other) const -> bool { return (flags & other) == other; } - auto entry::set_address(physical_frame frame) -> void + auto entry::set_address(allocator::physical_frame frame) -> void { arch::exception_handling::assert((frame.start_address() & ~0x000fffff'fffff000) == 0, "Start address is not aligned with Page"); flags = std::bitset<64U>(frame.start_address()) | flags; } -} // namespace teachos::arch::memory +} // namespace teachos::arch::memory::paging diff --git a/arch/x86_64/src/memory/paging/page_table.cpp b/arch/x86_64/src/memory/paging/page_table.cpp new file mode 100644 index 0000000..a1cbc72 --- /dev/null +++ b/arch/x86_64/src/memory/paging/page_table.cpp @@ -0,0 +1,65 @@ +#include "arch/memory/paging/page_table.hpp" + +#include "arch/exception_handling/assert.hpp" + +namespace teachos::arch::memory::paging +{ + page_table::page_table() + : current_level(LEVEL4) + , current_table(reinterpret_cast<table_content *>(0xfffffffffffff000)) + { + // Nothing to do + } + + auto page_table::zero_entries() -> void + { + constexpr size_t entry_amount = sizeof(current_table->entries) / sizeof(current_table->entries[0]); + for (size_t i = 0; i < entry_amount; ++i) + { + auto entry = this->operator[](i); + entry.set_unused(); + } + } + + auto page_table::next_table(std::size_t table_index) -> void + { + arch::exception_handling::assert(current_level != LEVEL1, + "[Page Table] Attempted to call next_table on level 1 page table"); + auto address = next_table_address(table_index); + + if (address.has_value()) + { + current_table = reinterpret_cast<table_content *>(*address); + current_level = static_cast<level>(current_level - 1U); + } + } + + auto page_table::operator[](std::size_t index) -> entry & + { + // C array is not bounds checked, therefore we have to check ourselves, to ensure no out of bounds reads, which + // could be incredibly hard to debug later. + arch::exception_handling::assert(index < PAGE_TABLE_ENTRY_COUNT, "[Page Table] index out of bounds"); + return current_table->entries[index]; + } + + auto page_table::operator[](std::size_t index) const -> entry const & + { + // C array is not bounds checked, therefore we have to check ourselves, to ensure no out of bounds reads, which + // could be incredibly hard to debug later. + arch::exception_handling::assert(index < PAGE_TABLE_ENTRY_COUNT, "[Page Table] index out of bounds"); + return current_table->entries[index]; + } + + auto page_table::next_table_address(std::size_t table_index) const -> std::optional<std::size_t> + { + auto entry = this->operator[](table_index); + + if (entry.contains_flags(entry::PRESENT) && !entry.contains_flags(entry::HUGE_PAGE)) + { + std::size_t const table_address = reinterpret_cast<std::size_t>(this); + return (table_address << 9) | (table_index << 12); + } + // TODO: Implement behaviour for huge pages currently not done + return std::nullopt; + } +} // namespace teachos::arch::memory::paging |
