aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/pre
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-12-12 14:11:07 +0100
committerFelix Morgner <felix.morgner@ost.ch>2025-12-12 14:11:07 +0100
commit682f28543be1ef7a315284c932075be1976e2930 (patch)
tree159198a415732989da7b0905ecd967db6e04e11b /arch/x86_64/pre
parent50c9c9a1d963e66f7658ab31e9ecd65bf227cfff (diff)
downloadkernel-682f28543be1ef7a315284c932075be1976e2930.tar.xz
kernel-682f28543be1ef7a315284c932075be1976e2930.zip
x86_64/pre: remove ported implementation
Diffstat (limited to 'arch/x86_64/pre')
-rw-r--r--arch/x86_64/pre/include/arch/memory/allocator/area_frame_allocator.hpp67
-rw-r--r--arch/x86_64/pre/include/arch/memory/allocator/concept.hpp21
-rw-r--r--arch/x86_64/pre/include/arch/memory/allocator/tiny_frame_allocator.hpp74
-rw-r--r--arch/x86_64/pre/include/arch/memory/main.hpp30
-rw-r--r--arch/x86_64/pre/include/arch/memory/multiboot/elf_symbols_section.hpp170
-rw-r--r--arch/x86_64/pre/include/arch/memory/multiboot/reader.hpp59
-rw-r--r--arch/x86_64/pre/include/arch/memory/paging/active_page_table.hpp206
-rw-r--r--arch/x86_64/pre/include/arch/memory/paging/inactive_page_table.hpp39
-rw-r--r--arch/x86_64/pre/include/arch/memory/paging/kernel_mapper.hpp180
-rw-r--r--arch/x86_64/pre/include/arch/memory/paging/page_entry.hpp121
-rw-r--r--arch/x86_64/pre/include/arch/memory/paging/page_table.hpp157
-rw-r--r--arch/x86_64/pre/include/arch/memory/paging/temporary_page.hpp64
-rw-r--r--arch/x86_64/pre/include/arch/memory/paging/virtual_page.hpp91
-rw-r--r--arch/x86_64/pre/src/memory/allocator/area_frame_allocator.cpp88
-rw-r--r--arch/x86_64/pre/src/memory/allocator/tiny_frame_allocator.cpp34
-rw-r--r--arch/x86_64/pre/src/memory/main.cpp77
-rw-r--r--arch/x86_64/pre/src/memory/multiboot/elf_symbols_section.cpp16
-rw-r--r--arch/x86_64/pre/src/memory/multiboot/reader.cpp135
-rw-r--r--arch/x86_64/pre/src/memory/paging/active_page_table.cpp101
-rw-r--r--arch/x86_64/pre/src/memory/paging/inactive_page_table.cpp20
-rw-r--r--arch/x86_64/pre/src/memory/paging/page_entry.cpp78
-rw-r--r--arch/x86_64/pre/src/memory/paging/page_table.cpp140
-rw-r--r--arch/x86_64/pre/src/memory/paging/temporary_page.cpp29
-rw-r--r--arch/x86_64/pre/src/memory/paging/virtual_page.cpp36
24 files changed, 0 insertions, 2033 deletions
diff --git a/arch/x86_64/pre/include/arch/memory/allocator/area_frame_allocator.hpp b/arch/x86_64/pre/include/arch/memory/allocator/area_frame_allocator.hpp
deleted file mode 100644
index a86c9b7..0000000
--- a/arch/x86_64/pre/include/arch/memory/allocator/area_frame_allocator.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef TEACHOS_X86_64_MEMORY_AREA_ALLOCATOR_HPP
-#define TEACHOS_X86_64_MEMORY_AREA_ALLOCATOR_HPP
-
-// #include "arch/memory/allocator/physical_frame.hpp"
-// #include "arch/memory/multiboot/reader.hpp"
-
-#include <optional>
-
-namespace x86_64::memory
-{
- /**
- * @brief Allocates memory linearly using memory areas read from the multiboot2 information pointer and leaks any
- * deallocated frames.
- */
- struct area_frame_allocator
- {
- /**
- * @brief Constructor.
- *
- * @param mem_info Structure containg all relevant information to map and allocate memory.
- */
- area_frame_allocator(multiboot::memory_information const & mem_info);
-
- /**
- * @brief Allocate memory by finding and returning a free physical frame.
- *
- * @note The physical_frame allocation executes multiple checks before returning
- * the physical_frame that is available to allocate. It must at least
- * do the following:
- * - check if the next_free_frame is within the current_area
- * - check if the next_free_frame is actually free
- * - update the next_free_frame after finding a free physical_frame
- *
- * @return next free physical frame or nullopt if none was found.
- */
- auto allocate_frame() -> std::optional<physical_frame>;
-
- /**
- * @brief Deallocates a previously allocated physical frame.
- *
- * @note Simply does nothing, because the simply area frame
- * allocator implementation does not keep track of free or used frames and can therefore not deallocate, because it
- * does not know which frames have been alocated in the first place.
- *
- * @param physical_frame Previously allocated physical_frame that should be deallocated.
- */
- auto deallocate_frame(physical_frame const & physical_frame) -> void;
-
- private:
- /**
- * @brief Find the next memory area and write it into current_area.
- */
- auto choose_next_area() -> void;
-
- physical_frame next_free_frame; ///< The physical_frame after the last allocated one.
- std::optional<multiboot::memory_area> current_area; ///< The current memory area.
- multiboot::memory_area_container const
- memory_areas; ///< All memory areas in custom container allows to use std::ranges.
- physical_frame const kernel_start; ///< The start address of the kernel code in memory.
- physical_frame const kernel_end; ///< The end address of the kernel code in memory.
- physical_frame const multiboot_start; ///< The start address of the multiboot code in memory.
- physical_frame const multiboot_end; ///< The end address of the multiboot code in memory.
- };
-
-} // namespace x86_64::memory
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_AREA_FRAME_ALLOCATOR_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/allocator/concept.hpp b/arch/x86_64/pre/include/arch/memory/allocator/concept.hpp
deleted file mode 100644
index 2d3f4ae..0000000
--- a/arch/x86_64/pre/include/arch/memory/allocator/concept.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_CONCEPT_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_CONCEPT_HPP
-
-#include "arch/memory/allocator/physical_frame.hpp"
-
-#include <optional>
-
-namespace teachos::arch::memory::allocator
-{
- /**
- * @brief Frame allocator concept required for allocating and deallocating physical frames in memory.
- */
- template<typename T>
- concept FrameAllocator = requires(T t, physical_frame const & a) {
- { t.allocate_frame() } -> std::same_as<std::optional<physical_frame>>;
- { t.deallocate_frame(a) } -> std::same_as<void>;
- };
-
-} // namespace teachos::arch::memory::allocator
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_CONCEPT_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/allocator/tiny_frame_allocator.hpp b/arch/x86_64/pre/include/arch/memory/allocator/tiny_frame_allocator.hpp
deleted file mode 100644
index 1e4746d..0000000
--- a/arch/x86_64/pre/include/arch/memory/allocator/tiny_frame_allocator.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_TINY_FRAME_ALLOCATOR_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_TINY_FRAME_ALLOCATOR_HPP
-
-#include "arch/memory/allocator/concept.hpp"
-#include "arch/memory/allocator/physical_frame.hpp"
-
-#include <array>
-
-namespace teachos::arch::memory::allocator
-{
- namespace
- {
- constexpr uint8_t TINY_ALLOCATOR_FRAMES_COUNT = 3U;
- }
-
- /**
- * @brief Allocates memory using memory areas read from the multiboot2 information pointer. Does not allocate its own
- * frames, but uses the necessary three frames provided by another allocator to map one virtual level 1 page entry and
- * the necessary upper layers.
- */
- struct tiny_frame_allocator
- {
- /**
- * @brief Constructor.
- *
- * @tparam T Contract the allocator that should be used to actually allocate and deallocate, the underlying three
- * frames has to follow.
- *
- * @param allocator Reference to an allocator following the FrameAllocator concept, which is used to allocate
- * entries when the underlying frames are created.
- */
- template<allocator::FrameAllocator T>
- tiny_frame_allocator(T & 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());
- }
- }
- }
-
- /**
- * @brief Allocate memory by finding and returning one of the three free physical frames.
- *
- * @return First free physical frames of the three frames held by this allocator or nullopt if we used up all three
- * frames already.
- */
- auto allocate_frame() -> std::optional<physical_frame>;
-
- /**
- * @brief Deallocates one of the three previously allocated physical frames.
- *
- * @note If more than the three frames are deallocated the method will halt execution, because it can only hold 3
- * frames.
- *
- * @param physical_frame Previously allocated physical_frame that should be deallocated.
- */
- auto deallocate_frame(physical_frame const & physical_frame) -> void;
-
- private:
- std::array<std::optional<physical_frame>, TINY_ALLOCATOR_FRAMES_COUNT> frames =
- {}; ///< Container that holds the frames allocated by another allocator.
- };
-
-} // namespace teachos::arch::memory::allocator
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_TINY_FRAME_ALLOCATOR_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/main.hpp b/arch/x86_64/pre/include/arch/memory/main.hpp
deleted file mode 100644
index d51815f..0000000
--- a/arch/x86_64/pre/include/arch/memory/main.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_MAIN_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_MAIN_HPP
-
-#include "arch/memory/paging/page_entry.hpp"
-
-#include <cstdint>
-
-namespace teachos::arch::memory
-{
-
- /**
- * @brief Maps a heap section to a page.
- *
- * @param heap_start Start-address of the heap.
- * @param heap_size Size of the heap.
- * @param additional_flags Additional flags to apply to the page entry.
- */
- auto remap_heap(std::size_t heap_start, std::size_t heap_size, paging::entry::bitset additional_flags) -> void;
-
- /**
- * @brief Initializes memory management.
- *
- * @note Enables the necessary register flags and remaps the kernel,
- * elf_sections, vga_text and the heap.
- */
- auto initialize_memory_management() -> void;
-
-} // namespace teachos::arch::memory
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_MAIN_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/multiboot/elf_symbols_section.hpp b/arch/x86_64/pre/include/arch/memory/multiboot/elf_symbols_section.hpp
deleted file mode 100644
index 348c159..0000000
--- a/arch/x86_64/pre/include/arch/memory/multiboot/elf_symbols_section.hpp
+++ /dev/null
@@ -1,170 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP
-
-// #include "arch/memory/multiboot/info.hpp"
-// #include "arch/stl/container.hpp"
-// #include "arch/stl/contiguous_pointer_iterator.hpp"
-
-#include <bitset>
-#include <cstdint>
-
-namespace teachos::arch::memory::multiboot
-{
- /**
- * @brief Defines all elf section types an elf section header can have.
- *
- * @note See https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-94076/index.html for more information.
- */
- enum struct elf_section_type : uint32_t
- {
- INACTIVE, ///< (SHT_NULL) Unused, meaning all values are zeroed out.
- PROGRAMM, ///< (SHT_PROGBITS) Program data (DATA, CODE).
- SYMBOL_TABLE, ///< (SHT_SYMBTAB) Contains actual entries pointed to in symbol hash table.
- STRING_TABLE, ///< (SHT_STRTAB) Contains symbols, section and debugging null-terminated strings.
- RELOCATION_ENTRY_WITH_ADDENDS, ///< (SHT_RELA) Only used on 64 bit systems.
- SYMBOL_HASH_TABLE, ///< (SHT_HASH) Hash table used by dynamic linker to locate symbols.
- DYNAMIC, ///< (SHT_DYNAMIC) Contains dynamic linking information.
- NOTE, ///< (SHT_NOTE) Stores information that marks files in some way.
- EMPTY, ///< (SHT_NOBITS) Program data section, that occupies no space in the file (.bss).
- RELOCATION_ENTRY_WITHOUT_ADDENDS, ///< (SHT_REL) Only used on 32 bit systems.
- UNSPECIFIED, ///< (SHT_SHLIB) Reserved but has unspecified semantics.
- DYNAMIC_SYMBOL_TABLE, ///< (SHT_DYNSYM) Holds minimal set of symbols adequate for dynamic linking.
- INITALIZATION_FUNCTION_ARRAY = 14, ///< (SHT_INIT_ARRAY) Array of pointers to intialization functions () -> void.
- TERMINATION_FUNCTION_ARRAY, ///< (SHT_FINI_ARRAY) Array of pointers to termination functions () -> void.
- PRE_INITALIZATION_FUNCTION_ARRAY ///< (SHT_PRE_INIT_ARRAY) Array of pointers to functions invoked before other
- ///< initalization functions () -> void.
- };
-
- /**
- * @brief Defines helper function for all states that the elf section flags of an elf section header can
- * have.
- *
- * @note See https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-94076/index.html for more information.
- */
- struct elf_section_flags
- {
- /**
- * @brief Possible set bits in our underlying std::bitset and the meaning when they are set.
- */
- enum bitset : uint32_t
- {
- WRITABLE = 1U << 0U, ///< (SHF_WRITE) Section is writable at runtime. If it isn't then the section
- ///< is assumed to be READONLY and only that flag is shown in the objdump.
- OCCUPIES_MEMORY = 1U << 1U, ///< (SHF_ALLOC) Section occupies memory during execution.
- ///< ALLOC flag is shown in the objdump.
- EXECUTABLE_CODE = 1U << 2U, ///< (SHF_EXECINSTR) Section is executable. CODE flag is shown in the object dump.
- DUPLICATE_DATA = 1U << 4U, ///< (SHF_MERGE) Section might be merged with another section.
- CONTAINS_STRING = 1U << 5U, ///< (SHF_STRINGS) Section contains null-terminated strings.
- SECTION_HEADER_INFO_IS_SECTION_HEADER_TABLE_INDEX =
- 1U << 6U, ///< (SHF_INFO_LINK) Section contains the section header table index in the (sh_info)
- ///< additional_information variable.
- PRESERVE_ORDERING_AFTER_COMBINATION =
- 1U << 7U, ///< (SHF_LINK_ORDER) Section preserves order after combining with another section.
- REQUIRES_SPECIAL_OS_PROCESSING =
- 1U << 8U, ///< (SHF_OS_NONCONFORMING) Section requires non-standard OS specific handling of its code or
- ///< data, which does not confirm to standard ELF specifications.
- SECTION_GROUP_MEMBER = 1U << 9U, ///< (SHF_GROUP) Section is a member of a section group.
- HOLDS_THREAD_LOCAL_DATA = 1U << 10U, ///< (SHF_TLS) Section holds thread-local data.
- COMPRESSED = 1U << 11U, ///< (SHF_COMPRESSED) Section contains compressed data.
- SPECIAL_ORDERING_REQUIREMENTS =
- 1U << 30U, ///< (SHF_ORDERED) Section has special ordering requirements, meaning it
- ///< should be ordered in relation to other sections of the same type.
- EXCLUDED_UNLESS_REFERENCED_OR_ALLOCATED = 1U << 31U, ///< (SHF_EXCLUDE)Section is excluded unless referenced or
- ///< allocated, used for LTO (Link-Time Optimizations).
- };
-
- /**
- * @brief Constructor.
- *
- * @param flags Actual value read from the elf section header, which should be converted into a std::bitset, to
- * allow reading the state of single bits more easily.
- */
- explicit elf_section_flags(uint64_t flags)
- : flags(flags)
- {
- // Nothing to do
- }
-
- /**
- * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset.
- *
- * @note Meaning that all bits that are set in the given std::bitset also have to be set in the underlyng
- * std::bitset. Any additional bits that are set are not relevant.
- *
- * @param other Flags that we want to compare against and check if the underlying std::bitset has the same bits set.
- * @return Whether the given flags are a subset or equivalent with the underlying std::bitset.
- */
- auto contains_flags(std::bitset<64U> other) const -> bool;
-
- /**
- * @brief Allows to compare the underlying std::bitset of two instances.
- *
- * @param other Other instance that we want to compare with.
- * @return Whether the underlying std::bitset of both types is the same.
- */
- auto operator==(elf_section_flags const & other) const -> bool = default;
-
- private:
- std::bitset<64U> flags; ///< Underlying bitset used to read the flags from. Bits 21 - 28 are reserved for operating
- ///< system specific semantics and bits 29 - 32 are reserved for processor specific
- ///< semantics. Bits 33 - 64 are unused for compatability with ELF32.
- };
-
- /**
- * @brief Defines the data included in a section header, where each section has exactly one section header.
- *
- * @note See https://refspecs.linuxbase.org/elf/gabi4+/ch4.sheader.html for more information.
- */
- struct elf_section_header
- {
- uint32_t name_table_index; ///< Index into the section header string table, specifies the name of the section.
- elf_section_type type; ///< Categorizes the sections content and semantics.
- elf_section_flags flags; ///< 1-bit flgas that describe section attributes.
- uint64_t physical_address; ///< If section appears in memory image of a process, gives address at which the
- ///< sections first byte should reside, otherwise 0.
- uint64_t file_offset; ///< Offset from the beginning of the file to the first byte in the section. SHT_NOBITS
- ///< contains the conceptual placement instead (because it occupies no space in the file).
- uint64_t section_size; ///< Complete section size in bytes, SHT_NOBITS may have non-zero value but will always
- ///< occupy no space in the file.
- uint32_t other_section; ///< Section header table index link, behaviour varies on type
- ///< https://refspecs.linuxbase.org/elf/gabi4+/ch4.sheader.html#sh_link.
- uint32_t additional_information; ///< Extra information, behaviour varies on type
- ///< https://refspecs.linuxbase.org/elf/gabi4+/ch4.sheader.html#sh_link.
- uint64_t address_alignment; ///< Possible address alignment constraints. Value of virutal_address must be 0 % value
- ///< of address_alignment. Value 0 or 1 mean no alignment constraints.
- uint64_t fixed_table_entry_size; ///< If sections holds table with fixed-sized entries, this gives the size in
- ///< bytes of each entry.
-
- /**
- * @brief Detect whether a section header is inactive or not, should always be the case for the first entry in the
- * sections table.
- *
- * @return Whether the current section header is actually null or not, requires all fields besides section_size and
- * other_section to contain 0.
- */
- auto is_null() const -> bool;
- };
-
- // /**
- // * @brief Defines an entry in the multi_boot_tag array of the multi_boot_info struct, of type
- // * multi_boot_tag_type::ELF_SECTIONS.
- // *
- // * @note The first section in the sections array will always be INACTIVE, there can only ever be one DYNAMIC
- // section
- // * and only either one DYNAMIC_SYMBOL_TABLE or SYMBOL_TABLE.
- // */
- // struct elf_symbols_section_header
- // {
- // tag info; ///< Basic multi_boot_tag information.
- // uint32_t number_of_sections; ///< Number of sections in the sections array.
- // uint32_t entry_size; ///< Size of each entry in the sections array.
- // uint32_t section_index; ///< Index to the string table used for symbol names.
- // std::byte end; ///< Marks the end of the tag, used to mark the beginning of any additional data.
- // ///< contained in the section, to ensure byte alignment is actually 4 byte.
- // };
-
- // using elf_section_header_container = stl::container<stl::contiguous_pointer_iterator<elf_section_header>>;
-
-} // namespace teachos::arch::memory::multiboot
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/multiboot/reader.hpp b/arch/x86_64/pre/include/arch/memory/multiboot/reader.hpp
deleted file mode 100644
index 275e5e2..0000000
--- a/arch/x86_64/pre/include/arch/memory/multiboot/reader.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP
-
-// #include "arch/memory/multiboot/elf_symbols_section.hpp"
-// #include "arch/memory/multiboot/memory_map.hpp"
-
-#include "arch/memory/multiboot/elf_symbols_section.hpp"
-
-#include <multiboot2/information.hpp>
-
-#include <cstdint>
-#include <span>
-
-namespace teachos::arch::memory::multiboot
-{
- /**
- * @brief Contains all relevant information to map and allocate memory that is read from the multiboot2 information
- * structure.
- */
- struct memory_information
- {
- std::size_t kernel_start; ///< Start address of the kernel code in memory.
- std::size_t kernel_end; ///< End address of the kernel code in memory.
- multiboot2::elf_symbols; ///< Contains non-owning pointers to all kernel sections.
- std::size_t multiboot_start; ///< Start address of the multiboot code in memory.
- std::size_t multiboot_end; ///< End address of the multiboot code in memory.
- // std::sp
- // memory_area_container areas; ///< Contains non-owning pointers to all memory areas.
- };
-
- /**
- * @brief Reads the relevant multiboot2 information data from memory.
- *
- * @note This is done using the multiboot_information_pointer, which marks the start of the multiboot2 data. The
- * indivdual headers we have to read are 8 byte aligned, whereas the data contained in those headers does not have to
- * be. All sections that are read additionaly receive some sanity to ensure the read address is actually pointing to
- * the expected structure, if they are not this method will assert.
- *
- * The memory_information variables are calcualted like this:
- * - kernel_start: Calculated by getting the lowest address specified in the elf symbols headers.
- * - kernel_end: Calculated by getting the highest address specified in the elf symbols headers and adding the length
- * of that section.
- * - multiboot_start: Calcualted by simply getting the value of the multiboot information pointer, because it already
- * contains the address pointint to the start of the multiboot2 data.
- * - multiboot_end: Calcualted by getting the value of the multiboot information pointer and adding the total size of
- * the complete multiboot2 data
- * - memory_areas: Calculated by simply accessing the address of the entries variable in the memory map header
- * structure.
- * - area_count: Calculated by subtracing the memory map header size from the total tag size, which results in the
- * remaining size (size of the entries array), this size is then divided by the size of one entry in that array, which
- * should be 24 bytes.
- *
- * @return Relevant data read from multiboot2.
- */
- auto read_multiboot2() -> memory_information;
-
-} // namespace teachos::arch::memory::multiboot
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/paging/active_page_table.hpp b/arch/x86_64/pre/include/arch/memory/paging/active_page_table.hpp
deleted file mode 100644
index abefd61..0000000
--- a/arch/x86_64/pre/include/arch/memory/paging/active_page_table.hpp
+++ /dev/null
@@ -1,206 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_ACTIVE_PAGE_TABLE_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_ACTIVE_PAGE_TABLE_HPP
-
-#include "arch/exception_handling/assert.hpp"
-#include "arch/kernel/cpu/tlb.hpp"
-#include "arch/memory/allocator/concept.hpp"
-#include "arch/memory/paging/virtual_page.hpp"
-
-#include <array>
-#include <bitset>
-#include <optional>
-
-namespace teachos::arch::memory::paging
-{
- /**
- * @brief Currently actively by the CPU used level 4 page table, is used to ensure there is only ever one valid
- * instance and it cannot be copied or constructed again.
- */
- struct active_page_table
- {
- /**
- * @brief Creates a single instance of an active level 4 page table table and returns the created instance or
- * alternatively returns the previously created instance instead. The instance is owned by this method and is
- * static, meaning it lives on for the complete lifetime of the program.
- *
- * @return Active single unique instance of the level 4 page table.
- */
- auto static create_or_get() -> active_page_table &;
-
- /**
- * @brief Index operator overload to access specific mutable entry directy of the level 4 page table.
- *
- * @param index Index of the entry we want to access and only read.
- * @return Entry at the given table index.
- */
- auto operator[](std::size_t index) -> entry &;
-
- /**
- * @brief Translates virtual address into corresponding physical address. Calls translate_page under the hood.
- *
- * @param address Virtual address we want to translate into physical one.
- * @return Physical address corresponding to the provided virtual address.
- */
- auto translate_address(virtual_address address) -> std::optional<allocator::physical_address>;
-
- /**
- * @brief Translates page into physical frame, will first attempt to parse normally using default page size and if
- * it failed attempt to parse using huge pages.
- *
- * @param page Page to translate into physical frame.
- * @return Physical frame corresponding to the provided virtual page.
- */
- auto translate_page(virtual_page page) -> std::optional<allocator::physical_frame>;
-
- /**
- * @brief Translates huge page into actual physical frame.
- *
- * @param page Page to translate into physical frame.
- * @return Physical frame corresponding to the provided virtual page.
- */
- auto translate_huge_page(virtual_page page) -> std::optional<allocator::physical_frame>;
-
- /**
- * @brief Maps a virtual page to a physical frame in the page table with the specified flags.
- *
- * @note Allocates and maps an entry in every page level if it does not exists yet down to level 1. If the level 1
- * page table already exists it halts execution instead.
- *
- * @tparam T Type constraint of the allocator, being that is follows the given concept and contains an allocate and
- * deallocate method.
- * @param allocator Reference to an allocator following the FrameAllocator concept, which is used to allocate
- * entries when a new page table is required.
- * @param page Virtual page that is being mapped.
- * @param frame Physical frame that the virtual page will be mapped to.
- * @param flags A bitset of flags that configure the page table entry for this mapping.
- */
- template<allocator::FrameAllocator T>
- auto map_page_to_frame(T & 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), flags);
- }
-
- 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);
- }
-
- /**
- * @brief Allocates the next free frame and then uses that frame to call map_page_to_frame.
- *
- * @see map_page_to_frame
- */
- template<allocator::FrameAllocator T>
- auto map_page_to_next_free_frame(T & 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);
- }
-
- /**
- * @brief Gets the corresponding page the given frame has to be contained in and uses that to call
- * map_page_to_frame.
- *
- * @see map_page_to_frame
- */
- template<allocator::FrameAllocator T>
- auto identity_map(T & 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);
- }
-
- /**
- * @brief Unmaps the virtual page from the previously mapped to physical frame and resets the flags.
- *
- * @note For the unmap function to deallocates and unmaps correctly, the entry in every page level if this page was
- * the last one up to level 4 should be unmapped and ensured to clear the Translation Lookaside Buffer, so that the
- * unmapped value is removed from cache as well. This is currently not done and instead we only dallocate and unmap
- * the level 1 page table entry, this is the case because it conflicts with our recursive mapping for the temporary
- * page, which requires the other page table entries to walk to the actual level 4 page table. If we remove all page
- * table entries beforehand, we therefore can not remap the kernel anymore.
- *
- * @tparam T Type constraint of the allocator, being that is follows the given concept and contains an allocate and
- * deallocate method.
- * @param allocator Reference to an allocator following the FrameAllocator concept, which is used to allocate
- * entries when a new page table is required.
- * @param page Virtual page that is being unmapped.
- */
- template<allocator::FrameAllocator T>
- auto unmap_page(T & 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);
- kernel::cpu::tlb_flush(page.start_address());
- }
-
- private:
- /**
- * @brief Private constructor should only be used by create or get method, which ensures to create only ever one
- * instance.
- *
- * @param active_handle Handle to the underlying currently active level 4 page table.
- */
- active_page_table(page_table_handle active_handle);
-
- /**
- * @brief Deleted copy constructor.
- */
- active_page_table(active_page_table const &) = delete;
-
- /**
- * @brief Deleted copy assignment operator.
- */
- active_page_table & operator=(active_page_table const &) = delete;
-
- /**
- * @brief Unmaps specific page at the current internal handle level.
- *
- * @tparam T Type constraint of the allocator, being that is follows the given concept and contains an allocate and
- * deallocate method.
- * @param allocator Reference to an allocator following the FrameAllocator concept, which is used to allocate
- * entries *when a new page table is required.
- * @param page Virtual page that is being unmapped.
- * @param handle Page Table handle we want to access the entry that should be cleared on.
- */
- template<allocator::FrameAllocator T>
- auto static unmap_page_table_entry(T & 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());
- }
-
- public:
- page_table_handle active_handle; ///< Underlying active level 4 page table
- };
-
-} // namespace teachos::arch::memory::paging
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_ACTIVE_PAGE_TABLE_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/paging/inactive_page_table.hpp b/arch/x86_64/pre/include/arch/memory/paging/inactive_page_table.hpp
deleted file mode 100644
index 8d96740..0000000
--- a/arch/x86_64/pre/include/arch/memory/paging/inactive_page_table.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_INACTIVE_PAGE_TABLE_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_INACTIVE_PAGE_TABLE_HPP
-
-#include "arch/memory/allocator/physical_frame.hpp"
-#include "arch/memory/paging/active_page_table.hpp"
-#include "arch/memory/paging/temporary_page.hpp"
-
-namespace teachos::arch::memory::paging
-{
- /**
- * @brief By the CPU used level 4 page table.
- */
- struct inactive_page_table
- {
- /**
- * @brief Constructor.
- *
- * @param frame Frame that should be mapped as the level 4 page table.
- */
- inactive_page_table(allocator::physical_frame frame);
-
- /**
- * @brief Constructor.
- *
- * @param frame Frame that should be mapped as the level 4 page table.
- * @param active_page_table Actual active page table that should be unmapped so we can map a new level 4
- * page table.
- * @param temporary_page Temporary page that should be used to map the given frame as the new level 4 page
- * table.
- */
- inactive_page_table(allocator::physical_frame frame, active_page_table & active_page_table,
- temporary_page & temporary_page);
-
- allocator::physical_frame page_table_level_4_frame; ///< Temporary level 4 page table
- };
-
-} // namespace teachos::arch::memory::paging
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_INACTIVE_PAGE_TABLE_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/paging/kernel_mapper.hpp b/arch/x86_64/pre/include/arch/memory/paging/kernel_mapper.hpp
deleted file mode 100644
index 581f142..0000000
--- a/arch/x86_64/pre/include/arch/memory/paging/kernel_mapper.hpp
+++ /dev/null
@@ -1,180 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_KERNEL_MAPPER_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_KERNEL_MAPPER_HPP
-
-#include "arch/kernel/cpu/control_register.hpp"
-#include "arch/memory/paging/active_page_table.hpp"
-#include "arch/memory/paging/inactive_page_table.hpp"
-#include "arch/memory/paging/temporary_page.hpp"
-#include "arch/video/vga/text.hpp"
-
-#include <algorithm>
-#include <array>
-
-namespace teachos::arch::memory::paging
-{
- /**
- * @brief Kernel mapper that allows to remap the kernel elf sections in C++.
- *
- * @tparam T Contract the allocator that should be used to allocate frames for the remapping process has to fulfill.
- */
- template<allocator::FrameAllocator T>
- struct kernel_mapper
- {
- /**
- * @brief Constructor.
- *
- * @param allocator Allocator that should be used to allocate frames for the remapping process.
- * @param mem_info Information about elf kernel sections required for remapping process.
- */
- kernel_mapper(T & allocator, multiboot::memory_information const & mem_info)
- : allocator(allocator)
- , mem_info(mem_info)
- {
- // Nothing to do
- }
-
- /**
- * @brief Remap the kernel, meaning we map the entire kernel and all of it's elf sections with the correct flags
- * into memory and then replace the created mapping with the current one.
- *
- * @note We have to use a workaround with an
- * inactive page table, that is not used by the CPU to ensure we are not changign memory that we are using. Because
- * remapping active kernel memory in the kernel wouldn't work.
- */
- auto remap_kernel() -> void
- {
- // Set Page Global Enable bit
- auto cr4 = kernel::cpu::read_control_register(kernel::cpu::control_register::CR4);
- kernel::cpu::write_control_register(kernel::cpu::control_register::CR4, cr4 | 0x80);
-
- temporary_page temporary_page{virtual_page{0xCAFE'BABE}, allocator};
- decltype(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);
- // Turn old level 4 page table, mapped by assembler code into stack guard page.
- // Only works if the identity mapped page tables by assembler are right above the stack.
- 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);
- }
-
- private:
- /**
- * @brief Remaps the kernel elf sections.
- *
- * This is done with switching the current level 4 page table recursive
- * mapping to any unmapped address in memory and then actually mapping the level 4 page table on that address.
- * Once the remapping process is done we can restore the original recursive mapping with the complete remapped
- * kernel.
- *
- * @note Because we change the entries we also have to ensure we flush the translation lookaside buffer, before we
- * map the entries.
- *
- * @param inactive_table Level 4 page table we temporarily map the kernel into.
- * @param temporary_page Temporary page that should be used for the mapping process and then
- * unmapped once finished.
- * @param active_table Active level 4 page table that has its recursive mapping overwritten temporarily and then
- * restored once the process is finished.
- */
- auto 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(
- kernel::cpu::read_control_register(kernel::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);
- kernel::cpu::tlb_flush_all();
- map_elf_kernel_sections(active_table);
-
- page_table_level4[511].set_entry(backup, entry::PRESENT | entry::WRITABLE);
- kernel::cpu::tlb_flush_all();
- temporary_page.unmap_page(active_table);
- }
-
- /**
- * @brief Switches the current active table pointed to by the CR3 register with another page table that is currently
- * inactive.
- *
- * @param new_table Inactive page table that should now be made active and replace the current active one.
- * @return The previous active page table.
- */
- auto switch_active_page_table(inactive_page_table new_table) -> inactive_page_table
- {
- auto const backup = allocator::physical_frame::containing_address(
- kernel::cpu::read_control_register(kernel::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();
- kernel::cpu::write_control_register(kernel::cpu::control_register::CR3, new_address);
- return old_table;
- }
-
- /**
- * @brief Maps the required entries according to every elf section and it's contained frames. Additionally each of
- * thoose frames gets the correct entry flags according to elf section flags.
- *
- * @param active_table Active level 4 page table that should be used to map the required elf sections into entries.
- * Has had its recursive mapping temporarily replaced and points to unmapped place in memory.
- */
- auto map_elf_kernel_sections(active_page_table & active_table) -> void
- {
- exception_handling::assert(!mem_info.sections.empty(), "[Kernel Mapper] Kernel elf sections empty");
- constexpr std::array<uint64_t, 6U> USER_SECTION_BASES = {
- 0x102000, // .boot_bss (Contains statically allocated variables)
- 0x209000, // .stl_text (Contains code for custom std implementations and standard library code)
- 0x217000, // .user_text (Contains the actual user code executed)
- 0x21E000, // .user_data (Contains static user variables)
-
- 0x20A000 // .text (Necessary, because symbols for all template standard library features are placed here if
- // they were first used in the Kernel Code Section)
- };
-
- 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 entry{section.flags};
-
- if (std::ranges::find(USER_SECTION_BASES, section.physical_address) != USER_SECTION_BASES.end())
- {
- entry.set_user_accessible();
- }
-
- 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);
- }
-
- T & allocator;
- multiboot::memory_information const &
- mem_info; ///< Information about elf kernel sections required for remapping process.
- };
-
-} // namespace teachos::arch::memory::paging
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_KERNEL_MAPPER_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/paging/page_entry.hpp b/arch/x86_64/pre/include/arch/memory/paging/page_entry.hpp
deleted file mode 100644
index 8147c5c..0000000
--- a/arch/x86_64/pre/include/arch/memory/paging/page_entry.hpp
+++ /dev/null
@@ -1,121 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_ENTRY_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_ENTRY_HPP
-
-#include "arch/memory/allocator/physical_frame.hpp"
-#include "arch/memory/multiboot/elf_symbols_section.hpp"
-
-#include <bitset>
-#include <optional>
-
-namespace teachos::arch::memory::paging
-{
- /**
- * @brief Marks a specific entry in an actual page table.
- */
- struct entry
- {
- /**
- * @brief Possible set bits in our underlying std::bitset and the meaning when they are set.
- */
- enum bitset : uint64_t
- {
- PRESENT = 1UL << 0UL, ///< Page is in memory and therefore present.
- ///< is assumed to be READONLY and only that flag is shown in the objdump.
- WRITABLE = 1UL << 1UL, ///< It is possible to write to the page.
- USER_ACCESSIBLE = 1UL << 2UL, ///< Page can be accessed in user mode instead of only in kernel mode code.
- WRITE_THROUGH_CACHING = 1UL << 3UL, ///< Write to the page go directly to memory instead of the cache.
- DISABLED_CACHING = 1UL << 4UL, ///< Page uses caching.
- ACCESSED = 1UL << 5UL, ///< Page is currently in use.
- DIRTY = 1UL << 6UL, ///< Page has been writen too.
- HUGE_PAGE = 1UL << 7UL, ///< Page is huge (2 MiB page size in P2 page table and 1 GiB in P3 page table,
- ///< instead of 4 KiB). Has to be false for P1 and P4 page tables.
- GLOBAL = 1UL << 8UL, ///< Page is not flushed from caches on address space switches (PGE bit of CR4 register
- ///< has to be set)
- EXECUTING_CODE_FORBIDDEN =
- 1UL << 63UL, ///< Page is forbidden from executing code (NXE bit in the EFER register has to be set)
- };
-
- /**
- * @brief Defaulted constructor.
- */
- entry() = default;
-
- /**
- * @brief Creates a new entry object from a 64bit address. Should follow the scheme where bit index 12 - 51 are the
- * actual address and the other bits are flags.
- *
- * @param flags Flags that will be passed to underlying std::bitset.
- */
- explicit entry(uint64_t flags);
-
- /**
- * @brief Creates a new entry converting the given elf section flags into the corresponding correct entry flags.
- *
- * @note Enables us to set the correct flags on a entry depending on which elf section it is contained in. For
- * example entries of .text sections should be executable and read only or entries of .data sections should be
- * writable but not executable.
- *
- * @param elf_flags Elf section flags we want to convert into entry flags.
- */
- explicit entry(multiboot::elf_section_flags elf_flags);
-
- /**
- * @brief Whether the current page is unused, meaning the underlying std::bitset is 0.
- *
- * @return Current page is in memory.
- */
- auto is_unused() const -> bool;
-
- /**
- * @brief Marks the page as unused, meaning the underlying std::bitset is set to 0.
- */
- auto set_unused() -> void;
-
- /**
- * @brief Marks the page as accessible in User mode, meaning the underlying std::bitset has the 2nd bit aditonally
- * set.
- */
- auto set_user_accessible() -> void;
-
- /**
- * @brief Calculates the physical frame this entry is pointing too, can be null if the page is not present in
- * memory.
- *
- * @return Calculated physical frame entry is pointing too.
- */
- auto calculate_pointed_to_frame() const -> std::optional<allocator::physical_frame>;
-
- /**
- * @brief Copies the address and flags from the given physical frame into the underlying std::bitset
- *
- * @param frame Physical frame that contains the address we want to copy into our underlying std::bitset.
- * @param additional_flags Entry flags which will be copied into our underlying std::bitset.
- */
- auto set_entry(allocator::physical_frame frame, std::bitset<64U> additional_flags) -> void;
-
- /**
- * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset.
- *
- * @note Meaning that all bits that are set in the given std::bitset also have to be set in the underlyng
- * std::bitset. Any additional bits that are set are not relevant.
- *
- * @param other Flags that we want to compare against and check if the underlying std::bitset has the same bits set.
- * @return Whether the given flags are a subset or equivalent with the underlying std::bitset.
- */
- auto contains_flags(std::bitset<64U> other) const -> bool;
-
- /**
- * @brief Extracts only the flags from the underlying entry and ignores all bits that contain the physical address.
- *
- * @return Extracted entry flags, without the physical address.
- */
- auto get_flags() const -> std::bitset<64U>;
-
- private:
- 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.
- };
-
-} // namespace teachos::arch::memory::paging
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_ENTRY_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/paging/page_table.hpp b/arch/x86_64/pre/include/arch/memory/paging/page_table.hpp
deleted file mode 100644
index 247086c..0000000
--- a/arch/x86_64/pre/include/arch/memory/paging/page_table.hpp
+++ /dev/null
@@ -1,157 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_TABLE_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_TABLE_HPP
-
-#include "arch/exception_handling/assert.hpp"
-#include "arch/memory/allocator/concept.hpp"
-#include "arch/memory/paging/page_entry.hpp"
-
-namespace teachos::arch::memory::paging
-{
- constexpr std::size_t PAGE_TABLE_ENTRY_COUNT = 512U; ///< Default entry count of a page table in x86_84 is 512.
-
- /**
- * @brief Forward delcaration of the page_table, because it should only be accessible over the handle.
- *
- * @note The actual methods or constructor are not defined meaning they are not callable from outside. Instead the
- * struct is only fully defined in the implementation (.cpp) file of the page table, and therefore the memthods are
- * only accesible in that file.
- */
- struct page_table;
-
- /**
- * @brief Handle that ensures accessing the page table is safe because it adds additional checks to the next_table
- * method and ensures it can only be called if the table level is not LEVEL1.
- */
- struct page_table_handle
- {
- /**
- * @brief Level of the page table.
- *
- * Level 1 will not be able to call next_table anymore, because it would result in
- * attempting to access memory that it should not.
- */
- enum level : uint8_t
- {
- LEVEL1,
- LEVEL2,
- LEVEL3,
- LEVEL4
- };
-
- /**
- * @brief Constructor.
- *
- * @param table Underlying page table the handle should point to.
- * @param table_level Level the underlying page table is on, used to ensure safety.
- */
- page_table_handle(page_table * table, level table_level);
-
- /**
- * @brief Set every entry of the page to unused.
- */
- auto zero_entries() -> void;
-
- /**
- * @brief Checks if all entries of this page are unused.
- */
- auto is_empty() const -> bool;
-
- /**
- * @brief Get the current table level.
- *
- * @return Current table level.
- */
- auto get_level() const -> level;
-
- /**
- * @brief Returns the next page table level from the given page table index. Meaning we
- * use an index into a Level 4 page table to get the according Level 3 page table.
- *
- * @note If this method is called with a Level 1 page table it will instead assert and halt execution, because there
- * is no furthere page table and mangeling up and returning the physical address would cause hard to debug issues.
- *
- * @param table_index Index of this page table in the page table one level lower.
- */
- auto next_table(std::size_t table_index) const -> std::optional<page_table_handle>;
-
- /**
- * @brief Call next_table and then checks if the table already exists, if it does not it will use the given
- * allocator to get the next free frame and set the entry to that instead.
- *
- * @param allocator Reference to an allocator following the FrameAllocator concept, which is used to allocate
- * entries when a new page table is required.
- * @param table_index Index of this page table in the page table one level lower.
- * @param flags A bitset of flags that configure the page table entry for this mapping.
- */
- template<allocator::FrameAllocator T>
- auto next_table_or_create(T & allocator, std::size_t table_index, std::bitset<64U> flags) -> 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();
- }
-
- // Check if the now created or previously created level 4, level 3 or level 2 page entry is used by user
- // accessible code. If it is that page entry needs to be user accesible as well.
- entry entry{flags.to_ulong()};
- if (entry.contains_flags(entry::USER_ACCESSIBLE))
- {
- this->operator[](table_index).set_user_accessible();
- }
- return next_handle.value();
- }
-
- /**
- * @brief Index operator overload to access specific mutable entry directy.
- *
- * @param index Index of the entry we want to access and only read.
- * @return Entry at the given table index.
- */
- auto operator[](std::size_t index) -> entry &;
-
- /**
- * @brief Index operator overload to access specific immutable entry directy.
- *
- * @param index Index of the entry we want to access and read or write.
- * @return Entry at the given table index.
- */
- auto operator[](std::size_t index) const -> entry const &;
-
- /**
- * @brief Pre decrement operator on the page table level enum, is defined so we can use it as a replacement
- * for an int index in a range based for loop.
- *
- * @note Will halt execution if called with page_table_handle::LEVEL1, because there is no level below. Has to be
- * defined as either a friend function or inline header method, because we define an operator of another type. In
- * this instance friend function was choosen, because the struct itself also requires the operator, but declaring
- * before the struct is not possible, because the enum is in the struct. This is inpossible because the struct
- * requires the operator declared before itself to work, and the operator requires the struct declared before itself
- * to work. Furthermore this allows the defintion of the method to be done in the cpp, avoiding includes in the
- * header file.
- *
- * @param value Value we want to decrement on
- * @return New level value decrement by one, meaning the level is also decrement by one Level4 --> Level3, ...
- */
- friend auto operator--(level & value) -> level &;
-
- private:
- page_table * table; ///< Handle to underlying page table, can never be null (invariant ensured by
- ///< constructor)
- level table_level; ///< Level page table is currently on, depends on how often next_level was
- ///< called successfuly.
- };
-
-} // namespace teachos::arch::memory::paging
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_TABLE_HPP
diff --git a/arch/x86_64/pre/include/arch/memory/paging/temporary_page.hpp b/arch/x86_64/pre/include/arch/memory/paging/temporary_page.hpp
deleted file mode 100644
index d0d7781..0000000
--- a/arch/x86_64/pre/include/arch/memory/paging/temporary_page.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_TEMPORARY_PAGE_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_TEMPORARY_PAGE_HPP
-
-#include "arch/memory/allocator/physical_frame.hpp"
-#include "arch/memory/allocator/tiny_frame_allocator.hpp"
-#include "arch/memory/paging/active_page_table.hpp"
-#include "arch/memory/paging/virtual_page.hpp"
-
-namespace teachos::arch::memory::paging
-{
- /**
- * @brief A temporary page used to remap the kernel.
- */
- struct temporary_page
- {
- /**
- * @brief Construct a new temporary page object.
- *
- * @tparam Type constraint of the allocator, being that is follows the given concept and contains an allocate and
- * deallocate method.
- * @param page Page to turn into temporary page.
- * @param allocator Frame allocator used to fill page.
- */
- template<allocator::FrameAllocator T>
- temporary_page(virtual_page page, T & allocator)
- : page{page}
- , allocator{allocator}
- {
- // Nothing to do
- }
-
- /**
- * @brief Unmap the current page.
- *
- * @param active_table The current active page table.
- */
- auto unmap_page(active_page_table & active_table) -> void;
-
- /**
- * @brief Map the temporary page to a frame.
- *
- * @param frame The frame to which the page is mapped.
- * @param active_table The current active page table.
- * @return level1 page table handle containing the mapped page.
- */
- auto map_table_frame(allocator::physical_frame frame, active_page_table & active_table) -> page_table_handle;
-
- private:
- /**
- * @brief Map the temporary page to a frame.
- *
- * @param frame The frame to which the page is mapped.
- * @param active_table The current active page table.
- * @return The virtual address of the page.
- */
- auto map_to_frame(allocator::physical_frame frame, active_page_table & active_table) -> virtual_address;
-
- virtual_page page; ///< Underlying virtual page we want to temporarily map.
- allocator::tiny_frame_allocator allocator; ///< Allocator that should be used to map the temporary page.
- };
-
-} // namespace teachos::arch::memory::paging
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_TEMPORARY_PAGE_HPP \ No newline at end of file
diff --git a/arch/x86_64/pre/include/arch/memory/paging/virtual_page.hpp b/arch/x86_64/pre/include/arch/memory/paging/virtual_page.hpp
deleted file mode 100644
index 1a20eae..0000000
--- a/arch/x86_64/pre/include/arch/memory/paging/virtual_page.hpp
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_VIRTUAL_PAGE_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_VIRTUAL_PAGE_HPP
-
-#include "arch/memory/allocator/physical_frame.hpp"
-#include "arch/memory/paging/page_table.hpp"
-
-#include <compare>
-#include <cstdint>
-#include <optional>
-
-namespace teachos::arch::memory::paging
-{
- using virtual_address = std::size_t;
-
- /**
- * @brief Virtual page entry contained in P1 page tables
- */
- struct virtual_page
- {
- /**
- * @brief Defaulted constructor.
- */
- constexpr virtual_page() = default;
-
- /**
- * @brief Constructor.
- *
- * @param page_number Index number of the current virtual page, used to distinguish it from other pages.
- */
- explicit constexpr virtual_page(std::size_t page_number)
- : page_number(page_number)
- {
- // Nothing to do
- }
-
- /**
- * @brief Returns the virtual page the given address is contained in.
- *
- * @param address Virtual address we want to get the corresponding virtual page for.
- * @return Frame the given address is contained in.
- */
- auto static containing_address(virtual_address address) -> virtual_page;
-
- /**
- * @brief Evaluates the start address of the virtual page.
- *
- * @return Start address of the virtual page.
- */
- auto start_address() const -> virtual_address;
-
- /**
- * @brief Calculates the index into the page table with the given level, which leads to this virtual page.
- *
- * @param level Level of the page table we want to calculate the index for.
- * @return Index into the page table with the given level.
- */
- auto get_level_index(page_table_handle::level level) const -> size_t;
-
- /**
- * @brief Post increment operator. Returns a copy of the value.
- *
- * @return Copy of the incremented underlying page number.
- */
- auto operator++(int) -> virtual_page;
-
- /**
- * @brief Pre increment operator. Returns a reference to the changed value.
- *
- * @return Reference to the incremented underlying page number.
- */
- auto operator++() -> virtual_page &;
-
- /**
- * @brief Defaulted equals operator.
- */
- auto operator==(virtual_page const & other) const -> bool = default;
-
- /**
- * @brief Defaulted three-way comparsion operator.
- */
- auto operator<=>(virtual_page const & other) const -> std::partial_ordering = default;
-
- std::size_t page_number =
- {}; ///< Index number of the current virtual page, used to distinguish it from other pages.
- };
-
- using page_container = stl::container<stl::forward_value_iterator<virtual_page>>;
-
-} // namespace teachos::arch::memory::paging
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_VIRTUAL_PAGE_HPP
diff --git a/arch/x86_64/pre/src/memory/allocator/area_frame_allocator.cpp b/arch/x86_64/pre/src/memory/allocator/area_frame_allocator.cpp
deleted file mode 100644
index 3105023..0000000
--- a/arch/x86_64/pre/src/memory/allocator/area_frame_allocator.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "arch/memory/allocator/area_frame_allocator.hpp"
-
-#include "arch/exception_handling/assert.hpp"
-
-#include <algorithm>
-#include <array>
-#include <ranges>
-
-namespace teachos::arch::memory::allocator
-{
- area_frame_allocator::area_frame_allocator(multiboot::memory_information const & mem_info)
- : next_free_frame()
- , current_area(std::nullopt)
- , memory_areas(mem_info.areas)
- , kernel_start(physical_frame::containing_address(mem_info.kernel_start))
- , kernel_end(physical_frame::containing_address(mem_info.kernel_end))
- , multiboot_start(physical_frame::containing_address(mem_info.multiboot_start))
- , multiboot_end(physical_frame::containing_address(mem_info.multiboot_end))
- {
- choose_next_area();
- }
-
- auto area_frame_allocator::choose_next_area() -> void
- {
- current_area = std::nullopt;
- auto next_area_with_free_frames = memory_areas | std::views::filter([this](auto const & area) {
- auto address = area.base_address + area.area_length - 1;
- return physical_frame::containing_address(address) >= next_free_frame;
- });
-
- auto const lowest_area_with_free_frames = std::ranges::min_element(
- next_area_with_free_frames, [](auto const & a, auto const & b) { return a.base_address < b.base_address; });
-
- if (lowest_area_with_free_frames != next_area_with_free_frames.end())
- {
- current_area = *lowest_area_with_free_frames;
- // Update the `next_free_frame` according to the new memory area
- auto const start_frame = physical_frame::containing_address(current_area.value().base_address);
- if (next_free_frame < start_frame)
- {
- next_free_frame = start_frame;
- }
- }
- }
-
- auto area_frame_allocator::allocate_frame() -> std::optional<physical_frame>
- {
- // Only try to allocate memory if current_area is not null, because
- // the current_area is null if there is no more available memory.
- if (!current_area.has_value())
- {
- return std::nullopt;
- }
-
- auto const address = current_area.value().base_address + current_area.value().area_length - 1;
- physical_frame current_area_last_frame = physical_frame::containing_address(address);
-
- if (next_free_frame > current_area_last_frame)
- {
- // All frames of current area are used, switch to next area.
- choose_next_area();
- }
- else if (next_free_frame >= kernel_start && next_free_frame <= kernel_end)
- {
- // `physical_frame` is used by the kernel or multiboot information structure.
- next_free_frame = allocator::physical_frame{kernel_end.frame_number + 1};
- }
- else if (next_free_frame >= multiboot_start && next_free_frame <= multiboot_end)
- {
- // `physical_frame` is used by the kernel or multiboot information structure.
- next_free_frame = allocator::physical_frame{multiboot_end.frame_number + 1};
- }
- else
- {
- // Frame is unused, increment `next_free_frame` and return it.
- next_free_frame.frame_number += 1;
- return next_free_frame;
- }
-
- // `physical_frame` was not valid, try it again with the updated `next_free_frame`.
- return allocate_frame();
- }
-
- auto area_frame_allocator::deallocate_frame(physical_frame const & physical_frame) -> void
- {
- (void)physical_frame;
- }
-} // namespace teachos::arch::memory::allocator
diff --git a/arch/x86_64/pre/src/memory/allocator/tiny_frame_allocator.cpp b/arch/x86_64/pre/src/memory/allocator/tiny_frame_allocator.cpp
deleted file mode 100644
index 3cdf9c7..0000000
--- a/arch/x86_64/pre/src/memory/allocator/tiny_frame_allocator.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "arch/memory/allocator/tiny_frame_allocator.hpp"
-
-#include "arch/exception_handling/panic.hpp"
-
-namespace teachos::arch::memory::allocator
-{
- auto tiny_frame_allocator::allocate_frame() -> std::optional<physical_frame>
- {
- for (auto & frame_option : frames)
- {
- if (frame_option.has_value())
- {
- auto value = frame_option;
- frame_option.reset();
- return value;
- }
- }
- return std::nullopt;
- }
-
- auto tiny_frame_allocator::deallocate_frame(physical_frame const & physical_frame) -> void
- {
- for (auto & frame_option : frames)
- {
- if (!frame_option.has_value())
- {
- frame_option.emplace(physical_frame);
- return;
- }
- }
- exception_handling::panic(
- "[Tiny Frame Allocator] Attempted to deallocate more than the 3 frames, that can be held");
- }
-} // namespace teachos::arch::memory::allocator
diff --git a/arch/x86_64/pre/src/memory/main.cpp b/arch/x86_64/pre/src/memory/main.cpp
deleted file mode 100644
index b5980db..0000000
--- a/arch/x86_64/pre/src/memory/main.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-#include "arch/memory/main.hpp"
-
-#include "arch/exception_handling/assert.hpp"
-#include "arch/kernel/cpu/control_register.hpp"
-#include "arch/kernel/cpu/msr.hpp"
-#include "arch/memory/allocator/area_frame_allocator.hpp"
-#include "arch/memory/allocator/concept.hpp"
-#include "arch/memory/heap/global_heap_allocator.hpp"
-#include "arch/memory/paging/active_page_table.hpp"
-#include "arch/memory/paging/kernel_mapper.hpp"
-
-#include <optional>
-
-namespace teachos::arch::memory
-{
- namespace
- {
- std::optional<allocator::area_frame_allocator> static frame_allocator;
-
- auto create_frame_allocator(multiboot::memory_information const & memory_information)
- -> allocator::area_frame_allocator &
- {
- frame_allocator.emplace(memory_information);
- return frame_allocator.value();
- }
-
- auto get_frame_allocator() -> allocator::area_frame_allocator &
- {
- exception_handling::assert(frame_allocator.has_value(),
- "[Initialization] Frame allocator has not been created yet");
- return frame_allocator.value();
- }
- } // namespace
-
- auto remap_heap(std::size_t heap_start, std::size_t heap_size, paging::entry::bitset additional_flags = {}) -> void
- {
- decltype(auto) allocator = get_frame_allocator();
- decltype(auto) active_table = paging::active_page_table::create_or_get();
- auto const start_page = paging::virtual_page::containing_address(heap_start);
- auto const end_page = ++(paging::virtual_page::containing_address(heap_start + heap_size - 1));
-
- paging::page_container::iterator const begin{start_page};
- paging::page_container::iterator const end{end_page};
- paging::page_container const pages{begin, end};
-
- constexpr auto base_flags = paging::entry::WRITABLE;
- auto const flags = base_flags | additional_flags;
-
- for (auto const & page : pages)
- {
- active_table.map_page_to_next_free_frame(allocator, page, flags);
- }
- }
-
- auto initialize_memory_management() -> void
- {
- bool static has_been_called = false;
- arch::exception_handling::assert(!has_been_called,
- "[Initialization] Memory management has already been initialized");
- has_been_called = true;
-
- auto const memory_information = multiboot::read_multiboot2();
- decltype(auto) allocator = create_frame_allocator(memory_information);
-
- kernel::cpu::set_cr0_bit(kernel::cpu::cr0_flags::WRITE_PROTECT);
- kernel::cpu::set_efer_bit(kernel::cpu::efer_flags::NXE);
-
- paging::kernel_mapper kernel(allocator, memory_information);
- kernel.remap_kernel();
- video::vga::text::write("Kernel remapping successful", video::vga::text::common_attributes::green_on_black);
- video::vga::text::newline();
-
- remap_heap(heap::KERNEL_HEAP_START, heap::KERNEL_HEAP_SIZE);
- video::vga::text::write("Heap remapping successful", video::vga::text::common_attributes::green_on_black);
- video::vga::text::newline();
- }
-} // namespace teachos::arch::memory
diff --git a/arch/x86_64/pre/src/memory/multiboot/elf_symbols_section.cpp b/arch/x86_64/pre/src/memory/multiboot/elf_symbols_section.cpp
deleted file mode 100644
index 3105120..0000000
--- a/arch/x86_64/pre/src/memory/multiboot/elf_symbols_section.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "arch/memory/multiboot/elf_symbols_section.hpp"
-
-namespace teachos::arch::memory::multiboot
-{
- auto elf_section_flags::contains_flags(std::bitset<64U> other) const -> bool
- {
- return (flags & other) == other;
- }
-
- auto elf_section_header::is_null() const -> bool
- {
- return name_table_index == 0U && type == elf_section_type::INACTIVE && flags == elf_section_flags(0U) &&
- physical_address == 0U && file_offset == 0U && additional_information == 0U && address_alignment == 0U &&
- fixed_table_entry_size == 0U;
- }
-} // namespace teachos::arch::memory::multiboot
diff --git a/arch/x86_64/pre/src/memory/multiboot/reader.cpp b/arch/x86_64/pre/src/memory/multiboot/reader.cpp
deleted file mode 100644
index b05e6b3..0000000
--- a/arch/x86_64/pre/src/memory/multiboot/reader.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-#include "arch/memory/multiboot/reader.hpp"
-
-#include "arch/boot/pointers.hpp"
-#include "arch/exception_handling/assert.hpp"
-#include "multiboot2/information.hpp"
-// #include "arch/memory/multiboot/elf_symbols_section.hpp"
-// #include "arch/memory/multiboot/info.hpp"
-
-#include <algorithm>
-#include <ranges>
-
-// namespace teachos::arch::memory::multiboot
-// {
-// namespace
-// {
-// template<typename T>
-// requires std::is_pointer<T>::value
-// auto align_to_8_byte_boundary(T ptr, uint32_t size) -> T
-// {
-// return reinterpret_cast<T>(reinterpret_cast<uint8_t *>(ptr) + ((size + 7) & ~7));
-// }
-
-// auto process_memory_map(memory_map_header * mminfo) -> memory_area_container
-// {
-// auto const expected_entry_size = mminfo->entry_size;
-// auto constexpr actual_entry_size = sizeof(memory_area);
-// exception_handling::assert(expected_entry_size == actual_entry_size,
-// "[Multiboot Reader] Unexpected memory area entry size");
-
-// auto const total_size = mminfo->info.size;
-// auto const total_entries_size = total_size - sizeof(memory_map_header) + actual_entry_size;
-// auto const number_of_entries = total_entries_size / actual_entry_size;
-
-// auto const begin = memory_area_container::iterator{&mminfo->entries};
-// auto const end = begin + number_of_entries;
-// return memory_area_container{begin, end};
-// }
-
-// auto process_elf_sections(elf_symbols_section_header * symbol, std::size_t & kernel_start, std::size_t &
-// kernel_end)
-// -> elf_section_header_container
-// {
-// auto const expected_entry_size = symbol->entry_size;
-// auto constexpr actual_entry_size = sizeof(elf_section_header);
-// exception_handling::assert(expected_entry_size == actual_entry_size,
-// "[Multiboot Reader] Unexpected elf section header entry size");
-
-// auto const expected_total_size = symbol->info.size;
-// auto const actual_total_entry_size = actual_entry_size * symbol->number_of_sections;
-// auto constexpr actual_total_section_size = sizeof(elf_symbols_section_header) - sizeof(uint32_t);
-// auto const actual_total_size = actual_total_entry_size + actual_total_section_size;
-// exception_handling::assert(expected_total_size == actual_total_size,
-// "[Multiboot Reader] Unexpected elf symbols section header total size");
-
-// auto const begin = elf_section_header_container::iterator{reinterpret_cast<elf_section_header
-// *>(&symbol->end)}; auto const end = begin + symbol->number_of_sections;
-// exception_handling::assert(begin->is_null(),
-// "[Multiboot Reader] Elf symbols section not starting with SHT_NULL section");
-
-// elf_section_header_container sections{begin, end};
-
-// auto allocated_sections = sections | std::views::filter([](auto const & section) {
-// return section.flags.contains_flags(elf_section_flags::OCCUPIES_MEMORY);
-// });
-
-// auto const elf_section_with_lowest_physical_address = std::ranges::min_element(
-// allocated_sections, [](auto const & a, auto const & b) { return a.physical_address < b.physical_address;
-// });
-
-// auto const elf_section_with_highest_physical_address =
-// std::ranges::max_element(allocated_sections, [](auto const & a, auto const & b) {
-// auto a_physical_address_end = a.physical_address + a.section_size;
-// auto b_physical_address_end = b.physical_address + b.section_size;
-// return a_physical_address_end < b_physical_address_end;
-// });
-
-// auto const symbol_table_section_count = std::ranges::count_if(sections, [](auto const & section) {
-// return section.type == elf_section_type::DYNAMIC_SYMBOL_TABLE || section.type ==
-// elf_section_type::SYMBOL_TABLE;
-// });
-// auto const dynamic_section_count = std::ranges::count_if(
-// sections, [](auto const & section) { return section.type == elf_section_type::DYNAMIC; });
-
-// exception_handling::assert(
-// symbol_table_section_count == 1U,
-// "[Multiboot Reader] ELF Specifications allows only (1) symbol table section, but got more");
-// exception_handling::assert(
-// dynamic_section_count <= 1U,
-// "[Multiboot Reader] ELF Specifications allows only (1) or less dynamic sections, but got more");
-
-// auto const lowest_elf_section = *elf_section_with_lowest_physical_address;
-// kernel_start = lowest_elf_section.physical_address;
-
-// auto const highest_elf_section = *elf_section_with_highest_physical_address;
-// kernel_end = highest_elf_section.physical_address + highest_elf_section.section_size;
-
-// return sections;
-// }
-// } // namespace
-
-// auto read_multiboot2() -> memory_information
-// {
-// memory_information mem_info{UINT64_MAX,
-// 0U,
-// elf_section_header_container{},
-// boot::multiboot_information_pointer,
-// 0U,
-// memory_area_container{}};
-
-// auto const multiboot_information_pointer = reinterpret_cast<info_header *>(boot::multiboot_information_pointer);
-// auto const multiboot_tag = &multiboot_information_pointer->tags;
-// mem_info.multiboot_end = mem_info.multiboot_start + multiboot_information_pointer->total_size;
-
-// for (auto tag = multiboot_tag; tag->type != tag_type::END; tag = align_to_8_byte_boundary(tag, tag->size))
-// {
-// switch (tag->type)
-// {
-// case tag_type::ELF_SECTIONS: {
-// auto const symbol = reinterpret_cast<elf_symbols_section_header *>(tag);
-// mem_info.sections = process_elf_sections(symbol, mem_info.kernel_start, mem_info.kernel_end);
-// break;
-// }
-// case tag_type::MEMORY_MAP: {
-// auto const mminfo = reinterpret_cast<memory_map_header *>(tag);
-// mem_info.areas = process_memory_map(mminfo);
-// break;
-// }
-// default:
-// // All other cases are not important and can be ignored.
-// break;
-// }
-// }
-// return mem_info;
-// }
-// } // namespace teachos::arch::memory::multiboot
diff --git a/arch/x86_64/pre/src/memory/paging/active_page_table.cpp b/arch/x86_64/pre/src/memory/paging/active_page_table.cpp
deleted file mode 100644
index 930588d..0000000
--- a/arch/x86_64/pre/src/memory/paging/active_page_table.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-#include "arch/memory/paging/active_page_table.hpp"
-
-namespace teachos::arch::memory::paging
-{
- namespace
- {
- constexpr paging::virtual_address PAGE_TABLE_LEVEL_4_ADDRESS = 0xffff'ffff'ffff'f000;
- }
-
- auto active_page_table::create_or_get() -> active_page_table &
- {
- page_table_handle static active_handle{reinterpret_cast<page_table *>(PAGE_TABLE_LEVEL_4_ADDRESS),
- page_table_handle::LEVEL4};
- active_page_table static active_page{active_handle};
- return active_page;
- }
-
- 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>
- {
- auto const offset = address % allocator::PAGE_FRAME_SIZE;
- auto const page = virtual_page::containing_address(address);
- auto const frame = translate_page(page);
-
- if (frame.has_value())
- {
- return frame.value().frame_number * allocator::PAGE_FRAME_SIZE + offset;
- }
-
- return std::nullopt;
- }
-
- auto active_page_table::translate_page(virtual_page page) -> std::optional<allocator::physical_frame>
- {
- auto current_handle = active_handle;
-
- for (auto level = page_table_handle::LEVEL4; level != page_table_handle::LEVEL1; --level)
- {
- auto const next_handle = current_handle.next_table(page.get_level_index(level));
- // If the next table method failed then it is highly likely that it was a huge page and we therefore have to
- // parse the table differently. Therefore, we attempt to parse it using the method required by huge pages.
- if (!next_handle.has_value())
- {
- return translate_huge_page(page);
- }
- current_handle = next_handle.value();
- }
-
- auto const level1_index = page.get_level_index(page_table_handle::LEVEL1);
- auto const level1_entry = current_handle[level1_index];
- return level1_entry.calculate_pointed_to_frame();
- }
-
- auto active_page_table::translate_huge_page(virtual_page page) -> std::optional<allocator::physical_frame>
- {
- auto current_handle = active_handle;
- auto level3_handle = current_handle.next_table(page.get_level_index(page_table_handle::LEVEL4));
-
- if (!level3_handle.has_value())
- {
- return std::nullopt;
- }
-
- auto const level3_entry = level3_handle.value()[page.get_level_index(page_table_handle::LEVEL3)];
- auto const level3_frame = level3_entry.calculate_pointed_to_frame();
- if (level3_frame.has_value() && level3_entry.contains_flags(entry::HUGE_PAGE))
- {
- exception_handling::assert(
- level3_frame.value().frame_number % (PAGE_TABLE_ENTRY_COUNT * PAGE_TABLE_ENTRY_COUNT) == 0U,
- "[Page Mapper] Physical address must be 1 GiB aligned");
- return allocator::physical_frame{level3_frame.value().frame_number +
- page.get_level_index(page_table_handle::LEVEL2) * PAGE_TABLE_ENTRY_COUNT +
- page.get_level_index(page_table_handle::LEVEL1)};
- }
-
- auto level2_handle = level3_handle.value().next_table(page.get_level_index(page_table_handle::LEVEL3));
- if (level2_handle.has_value())
- {
- auto const level2_entry = level2_handle.value()[page.get_level_index(page_table_handle::LEVEL2)];
- auto const level2_frame = level2_entry.calculate_pointed_to_frame();
- if (level2_frame.has_value() && level2_entry.contains_flags(entry::HUGE_PAGE))
- {
- exception_handling::assert(level2_frame.value().frame_number % PAGE_TABLE_ENTRY_COUNT == 0U,
- "[Page Mapper] Physical address must be 2 MiB aligned");
- return allocator::physical_frame{level2_frame.value().frame_number +
- page.get_level_index(page_table_handle::LEVEL1)};
- }
- }
- return std::nullopt;
- }
-
- active_page_table::active_page_table(page_table_handle active_handle)
- : active_handle(active_handle)
- {
- // Nothing to do
- }
-} // namespace teachos::arch::memory::paging
diff --git a/arch/x86_64/pre/src/memory/paging/inactive_page_table.cpp b/arch/x86_64/pre/src/memory/paging/inactive_page_table.cpp
deleted file mode 100644
index 4e0610e..0000000
--- a/arch/x86_64/pre/src/memory/paging/inactive_page_table.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "arch/memory/paging/inactive_page_table.hpp"
-
-namespace teachos::arch::memory::paging
-{
- inactive_page_table::inactive_page_table(allocator::physical_frame frame)
- : page_table_level_4_frame{frame}
- {
- // Nothing to do
- }
-
- inactive_page_table::inactive_page_table(allocator::physical_frame frame, active_page_table & active_page_table,
- temporary_page & temporary_page)
- : page_table_level_4_frame{frame}
- {
- auto table = temporary_page.map_table_frame(page_table_level_4_frame, active_page_table);
- table.zero_entries();
- table[511].set_entry(page_table_level_4_frame, entry::PRESENT | entry::WRITABLE);
- temporary_page.unmap_page(active_page_table);
- }
-} // namespace teachos::arch::memory::paging
diff --git a/arch/x86_64/pre/src/memory/paging/page_entry.cpp b/arch/x86_64/pre/src/memory/paging/page_entry.cpp
deleted file mode 100644
index ec45068..0000000
--- a/arch/x86_64/pre/src/memory/paging/page_entry.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-#include "arch/memory/paging/page_entry.hpp"
-
-#include "arch/exception_handling/assert.hpp"
-
-namespace teachos::arch::memory::paging
-{
- namespace
- {
- constexpr std::size_t PHYSICAL_ADDRESS_MASK = 0x000f'ffff'ffff'f000;
- } // namespace
-
- entry::entry(uint64_t flags)
- : flags(flags)
- {
- // Nothing to do.
- }
-
- entry::entry(multiboot::elf_section_flags elf_flags)
- {
- if (elf_flags.contains_flags(multiboot::elf_section_flags::OCCUPIES_MEMORY))
- {
- flags |= entry::PRESENT;
- }
-
- if (elf_flags.contains_flags(multiboot::elf_section_flags::WRITABLE))
- {
- flags |= entry::WRITABLE;
- }
-
- if (!elf_flags.contains_flags(multiboot::elf_section_flags::EXECUTABLE_CODE))
- {
- flags |= entry::EXECUTING_CODE_FORBIDDEN;
- }
- }
-
- auto entry::is_unused() const -> bool
- {
- return flags == 0U;
- }
-
- auto entry::set_unused() -> void
- {
- flags = 0U;
- }
-
- auto entry::set_user_accessible() -> void
- {
- flags |= entry::USER_ACCESSIBLE;
- }
-
- auto entry::calculate_pointed_to_frame() const -> std::optional<allocator::physical_frame>
- {
- if (contains_flags(PRESENT))
- {
- auto const address = flags.to_ulong() & PHYSICAL_ADDRESS_MASK;
- return allocator::physical_frame::containing_address(address);
- }
- return std::nullopt;
- }
-
- auto entry::contains_flags(std::bitset<64U> other) const -> bool
- {
- return (flags & other) == other;
- }
-
- auto entry::set_entry(allocator::physical_frame frame, std::bitset<64U> additional_flags) -> void
- {
- exception_handling::assert((frame.start_address() & ~PHYSICAL_ADDRESS_MASK) == 0,
- "[Paging Entry] Start address is not aligned with page");
-
- flags = frame.start_address() | additional_flags.to_ulong();
- }
-
- auto entry::get_flags() const -> std::bitset<64U>
- {
- return flags.to_ulong() & ~PHYSICAL_ADDRESS_MASK;
- }
-} // namespace teachos::arch::memory::paging
diff --git a/arch/x86_64/pre/src/memory/paging/page_table.cpp b/arch/x86_64/pre/src/memory/paging/page_table.cpp
deleted file mode 100644
index e79c3e5..0000000
--- a/arch/x86_64/pre/src/memory/paging/page_table.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-#include "arch/memory/paging/page_table.hpp"
-
-#include <algorithm>
-#include <array>
-#include <memory>
-
-/*
- * This is a linker variable reference. This referenc cannot reside inside a namespace, because in
- * that case the compiler would try to find arch::memory::paging::_end_of_image inside the ELF file.
- */
-extern char _end_of_image;
-
-namespace teachos::arch::memory::paging
-{
- /**
- * @brief A Page table containing 512 entries.
- */
- struct page_table
- {
- auto zero_entries() -> void;
-
- auto is_empty() const -> bool;
-
- auto next_table(std::size_t table_index) const -> std::optional<page_table *>;
-
- auto operator[](std::size_t index) -> entry &;
-
- auto operator[](std::size_t index) const -> entry const &;
-
- private:
- /**
- * @brief Calculates the address of the next page table level for the given table index.
- *
- * @note The next page table address is only valid if the corresponding entry is present and not a huge page.
- * Meaning we use an index into a Level 4 page table to get the according Level 3 page table address.
- *
- * @param table_index Index of this page table in the page table one level higher.
- * @return An optional of the address of the next page table or null.
- */
- auto next_table_address(std::size_t table_index) const -> std::optional<std::size_t>;
-
- std::array<entry, PAGE_TABLE_ENTRY_COUNT> entries =
- {}; ///< Entries containing addresses to page tables of a level below or
- ///< actual virtual addresses for the level 1 page table.
- };
-
- auto page_table::zero_entries() -> void
- {
- std::ranges::for_each(entries, [](auto & entry) { entry.set_unused(); });
- }
-
- auto page_table::is_empty() const -> bool
- {
- return std::all_of(entries.begin(), entries.end(), [](entry const & entry) { return entry.is_unused(); });
- }
-
- auto page_table::next_table(std::size_t table_index) const -> std::optional<page_table *>
- {
- auto const address = next_table_address(table_index);
- if (address.has_value())
- {
- return reinterpret_cast<page_table *>(address.value());
- }
- return std::nullopt;
- }
-
- auto page_table::operator[](std::size_t index) -> entry &
- {
- exception_handling::assert(index < PAGE_TABLE_ENTRY_COUNT, "[Page Table] Index out of bounds");
- return entries[index];
- }
-
- auto page_table::operator[](std::size_t index) const -> entry const &
- {
- exception_handling::assert(index < PAGE_TABLE_ENTRY_COUNT, "[Page Table] Index out of bounds");
- return entries[index];
- }
-
- auto page_table::next_table_address(std::size_t table_index) const -> std::optional<std::size_t>
- {
- auto const entry = this->operator[](table_index);
-
- if (entry.contains_flags(entry::PRESENT) && !entry.contains_flags(entry::HUGE_PAGE))
- {
- auto const table_address = reinterpret_cast<std::size_t>(this);
- return ((table_address << 9) | (table_index << 12));
- }
- return std::nullopt;
- }
-
- page_table_handle::page_table_handle(page_table * table, page_table_handle::level table_level)
- : table(table)
- , table_level(table_level)
- {
- exception_handling::assert(table != nullptr,
- "[Page Table] Attempted to pass nullptr as table to page table table method");
- }
-
- auto page_table_handle::zero_entries() -> void
- {
- table->zero_entries();
- }
-
- auto page_table_handle::is_empty() const -> bool
- {
- return table->is_empty();
- }
-
- auto page_table_handle::next_table(std::size_t table_index) const -> std::optional<page_table_handle>
- {
- exception_handling::assert(table_level != page_table_handle::LEVEL1,
- "[Page Table] Attempted to call next_table on level 1 page table");
- auto const next_table = table->next_table(table_index);
- if (next_table.has_value())
- {
- auto const new_level = static_cast<page_table_handle::level>(table_level - 1);
- return page_table_handle{next_table.value(), new_level};
- }
- return std::nullopt;
- }
-
- auto page_table_handle::get_level() const -> page_table_handle::level
- {
- return table_level;
- }
-
- auto page_table_handle::operator[](std::size_t index) -> entry &
- {
- return table->operator[](index);
- }
-
- auto operator--(page_table_handle::level & value) -> page_table_handle::level &
- {
- exception_handling::assert(value != page_table_handle::LEVEL1,
- "[Page table] Attempted to decrement enum to value outside of range");
- auto new_value = static_cast<std::underlying_type<page_table_handle::level>::type>(value);
- value = static_cast<page_table_handle::level>(--new_value);
- return value;
- }
-} // namespace teachos::arch::memory::paging
diff --git a/arch/x86_64/pre/src/memory/paging/temporary_page.cpp b/arch/x86_64/pre/src/memory/paging/temporary_page.cpp
deleted file mode 100644
index 8e73523..0000000
--- a/arch/x86_64/pre/src/memory/paging/temporary_page.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "arch/memory/paging/temporary_page.hpp"
-
-#include "arch/memory/paging/page_entry.hpp"
-
-namespace teachos::arch::memory::paging
-{
- auto temporary_page::map_table_frame(allocator::physical_frame frame, active_page_table & active_table)
- -> page_table_handle
- {
- page_table_handle handle{reinterpret_cast<page_table *>(map_to_frame(frame, active_table)),
- page_table_handle::LEVEL1};
- return handle;
- }
-
- auto temporary_page::map_to_frame(allocator::physical_frame frame, active_page_table & active_table)
- -> virtual_address
- {
- exception_handling::assert(!active_table.translate_page(page).has_value(),
- "[Temporary page] Page is already mapped");
-
- active_table.map_page_to_frame(allocator, page, frame, entry::WRITABLE);
- return page.start_address();
- }
-
- auto temporary_page::unmap_page(active_page_table & active_table) -> void
- {
- active_table.unmap_page(allocator, page);
- }
-} // namespace teachos::arch::memory::paging
diff --git a/arch/x86_64/pre/src/memory/paging/virtual_page.cpp b/arch/x86_64/pre/src/memory/paging/virtual_page.cpp
deleted file mode 100644
index 8d34918..0000000
--- a/arch/x86_64/pre/src/memory/paging/virtual_page.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "arch/memory/paging/virtual_page.hpp"
-
-#include "arch/exception_handling/assert.hpp"
-
-namespace teachos::arch::memory::paging
-{
- auto virtual_page::containing_address(virtual_address address) -> virtual_page
- {
- exception_handling::assert(address < 0x0000'8000'0000'0000 || address >= 0xffff'8000'0000'0000,
- "[Virtual Page] Attempted to create virtual page from invalid address");
- return virtual_page{address / allocator::PAGE_FRAME_SIZE};
- }
-
- auto virtual_page::start_address() const -> virtual_address
- {
- return page_number * allocator::PAGE_FRAME_SIZE;
- }
-
- auto virtual_page::get_level_index(page_table_handle::level level) const -> size_t
- {
- return (page_number >> (level * 9U)) & 0x1FF;
- }
-
- auto virtual_page::operator++(int) -> virtual_page
- {
- virtual_page const old_value = *this;
- ++page_number;
- return old_value;
- }
-
- auto virtual_page::operator++() -> virtual_page &
- {
- ++page_number;
- return *this;
- }
-} // namespace teachos::arch::memory::paging