aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src')
-rw-r--r--arch/x86_64/src/kernel/main.cpp4
-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.cpp22
-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.cpp65
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