aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/include
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-07-17 21:09:02 +0000
committerFelix Morgner <felix.morgner@ost.ch>2025-07-18 13:02:34 +0200
commit14ed096fc5de6844cb116f3319c0d03043d26ea2 (patch)
treee78cc753b2d6dcabd703aebc4b9bea1783cc2e6d /arch/x86_64/include
parent891ca8834122e55638d33a129baab7292b8ed6d0 (diff)
downloadteachos-14ed096fc5de6844cb116f3319c0d03043d26ea2.tar.xz
teachos-14ed096fc5de6844cb116f3319c0d03043d26ea2.zip
x86-64: prepare new architecture
Diffstat (limited to 'arch/x86_64/include')
-rw-r--r--arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp12
-rw-r--r--arch/x86_64/include/arch/memory/allocator/physical_frame.hpp86
-rw-r--r--arch/x86_64/include/x86_64/memory/address.hpp47
-rw-r--r--arch/x86_64/include/x86_64/memory/frame.hpp95
-rw-r--r--arch/x86_64/include/x86_64/memory/region_allocator.hpp76
5 files changed, 224 insertions, 92 deletions
diff --git a/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp b/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp
index 6cb5f56..a86c9b7 100644
--- a/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp
+++ b/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp
@@ -1,12 +1,12 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_AREA_FRAME_ALLOCATOR_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_AREA_FRAME_ALLOCATOR_HPP
+#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 "arch/memory/allocator/physical_frame.hpp"
+// #include "arch/memory/multiboot/reader.hpp"
#include <optional>
-namespace teachos::arch::memory::allocator
+namespace x86_64::memory
{
/**
* @brief Allocates memory linearly using memory areas read from the multiboot2 information pointer and leaks any
@@ -62,6 +62,6 @@ namespace teachos::arch::memory::allocator
physical_frame const multiboot_end; ///< The end address of the multiboot code in memory.
};
-} // namespace teachos::arch::memory::allocator
+} // namespace x86_64::memory
#endif // TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_AREA_FRAME_ALLOCATOR_HPP
diff --git a/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp b/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp
deleted file mode 100644
index cb6c5b3..0000000
--- a/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_PHYSICAL_FRAME_HPP
-#define TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_PHYSICAL_FRAME_HPP
-
-#include "arch/stl/container.hpp"
-#include "arch/stl/forward_value_iterator.hpp"
-
-#include <compare>
-#include <cstdint>
-#include <iterator>
-
-namespace teachos::arch::memory::allocator
-{
- using physical_address = std::size_t;
-
- std::size_t constexpr PAGE_FRAME_SIZE = 4096U; ///< Default page size of x86_84 is always 4KiB.
-
- /**
- * @brief Specific physical frame containing helper functions to determine if a specific address is in that
- * physical frame or not.
- */
- struct physical_frame
- {
- /**
- * @brief Defaulted constructor.
- */
- constexpr physical_frame() = default;
-
- /**
- * @brief Constructor.
- *
- * @param frame_number Index number that should be assigned to this physical frame.
- */
- explicit constexpr physical_frame(std::size_t frame_number)
- : frame_number(frame_number)
- {
- // Nothing to do
- }
-
- /**
- * @brief Returns the physical frame the given address is contained in.
- *
- * @param address Physical address we want to get the corresponding physical frame for.
- * @return Frame the given address is contained in.
- */
- auto static containing_address(physical_address address) -> physical_frame;
-
- /**
- * @brief Get the start address of this physical frame.
- *
- * @return Start address of the physical frame.
- */
- auto start_address() const -> physical_address;
-
- /**
- * @brief Post increment operator. Returns a copy of the value.
- *
- * @return Copy of the incremented underlying frame number.
- */
- auto operator++(int) -> physical_frame;
-
- /**
- * @brief Pre increment operator. Returns a reference to the changed value.
- *
- * @return Reference to the incremented underlying frame number.
- */
- auto operator++() -> physical_frame &;
-
- /**
- * @brief Defaulted equals operator.
- */
- auto operator==(physical_frame const & other) const -> bool = default;
-
- /**
- * @brief Defaulted three-way comparsion operator.
- */
- auto operator<=>(physical_frame const & other) const -> std::partial_ordering = default;
-
- std::size_t frame_number =
- {}; ///< Index number of the current physical frame, used to distinguish it from other frames.
- };
-
- using frame_container = stl::container<stl::forward_value_iterator<physical_frame>>;
-
-} // namespace teachos::arch::memory::allocator
-
-#endif // TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_PHYSICAL_FRAME_HPP
diff --git a/arch/x86_64/include/x86_64/memory/address.hpp b/arch/x86_64/include/x86_64/memory/address.hpp
new file mode 100644
index 0000000..20e9655
--- /dev/null
+++ b/arch/x86_64/include/x86_64/memory/address.hpp
@@ -0,0 +1,47 @@
+#ifndef TEACHOS_X86_64_MEMORY_ADDRESS_HPP
+#define TEACHOS_X86_64_MEMORY_ADDRESS_HPP
+
+#include <bit>
+#include <compare>
+#include <cstddef>
+#include <cstdint>
+
+namespace teachos::x86_64::memory
+{
+
+ enum struct address_type : bool
+ {
+ linear,
+ physical,
+ };
+
+ template<address_type Type>
+ struct address
+ {
+ constexpr explicit address(std::uintptr_t value) noexcept
+ : m_value{value}
+ {
+ }
+
+ explicit address(std::byte * pointer) noexcept
+ : m_value{std::bit_cast<std::uintptr_t>(pointer)}
+ {
+ }
+
+ explicit operator std::byte *() const noexcept { return std::bit_cast<std::byte *>(m_value); }
+
+ auto constexpr operator<=>(address const &) const noexcept -> std::strong_ordering = default;
+ auto constexpr operator==(address const &) const noexcept -> bool = default;
+
+ auto constexpr raw() const noexcept -> std::uintptr_t { return m_value; }
+
+ private:
+ std::uintptr_t m_value{};
+ };
+
+ using linear_address = address<address_type::linear>;
+ using physical_address = address<address_type::physical>;
+
+} // namespace teachos::x86_64::memory
+
+#endif \ No newline at end of file
diff --git a/arch/x86_64/include/x86_64/memory/frame.hpp b/arch/x86_64/include/x86_64/memory/frame.hpp
new file mode 100644
index 0000000..21565fd
--- /dev/null
+++ b/arch/x86_64/include/x86_64/memory/frame.hpp
@@ -0,0 +1,95 @@
+#ifndef TEACHOS_X86_64_MEMORY_FRAME_HPP
+#define TEACHOS_X86_64_MEMORY_FRAME_HPP
+
+#include "x86_64/memory/address.hpp"
+
+#include <compare>
+#include <cstddef>
+
+namespace teachos::x86_64::memory
+{
+ /**
+ * @brief Specific physical frame containing helper functions to determine if a specific address is in that
+ * physical frame or not.
+ */
+ struct frame
+ {
+ auto static inline constexpr DEFAULT_SIZE = std::size_t{4096}; ///< Default page size of x86_84 is always 4KiB.
+
+ /**
+ * @brief Defaulted constructor.
+ */
+ constexpr frame() = default;
+
+ /**
+ * @brief Constructor.
+ *
+ * @param frame_number Index number that should be assigned to this physical frame.
+ */
+ explicit constexpr frame(std::size_t number)
+ : m_number(number)
+ {
+ }
+
+ /**
+ * @brief Returns the physical frame the given address is contained in.
+ *
+ * @param address Physical address we want to get the corresponding physical frame for.
+ * @return Frame the given address is contained in.
+ */
+ auto constexpr static containing(physical_address address) noexcept -> frame
+ {
+ return frame{address.raw() / DEFAULT_SIZE};
+ }
+
+ /**
+ * @brief Get the start address of this physical frame.
+ *
+ * @return Start address of the physical frame.
+ */
+ auto constexpr start_address() const noexcept -> physical_address
+ {
+ return physical_address{m_number * DEFAULT_SIZE};
+ }
+
+ auto constexpr operator+(std::size_t offset) const noexcept -> frame { return frame{m_number + offset}; }
+
+ /**
+ * @brief Post increment operator. Returns a copy of the value.
+ *
+ * @return Copy of the incremented underlying frame number.
+ */
+ auto constexpr operator++(int) noexcept -> frame
+ {
+ auto copy = *this;
+ return ++copy;
+ }
+
+ /**
+ * @brief Pre increment operator. Returns a reference to the changed value.
+ *
+ * @return Reference to the incremented underlying frame number.
+ */
+ auto constexpr operator++() noexcept -> frame &
+ {
+ ++m_number;
+ return *this;
+ }
+
+ /**
+ * @brief Defaulted equals operator.
+ */
+ auto constexpr operator==(frame const & other) const noexcept -> bool = default;
+
+ /**
+ * @brief Defaulted three-way comparison operator.
+ */
+ auto constexpr operator<=>(frame const & other) const noexcept -> std::strong_ordering = default;
+
+ private:
+ std::size_t m_number{}; ///< Index number of the current physical frame, used to distinguish it from other frames.
+ };
+
+} // namespace teachos::x86_64::memory
+
+#endif // TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_frame_HPP
diff --git a/arch/x86_64/include/x86_64/memory/region_allocator.hpp b/arch/x86_64/include/x86_64/memory/region_allocator.hpp
new file mode 100644
index 0000000..23bea10
--- /dev/null
+++ b/arch/x86_64/include/x86_64/memory/region_allocator.hpp
@@ -0,0 +1,76 @@
+#ifndef TEACHOS_X86_64_MEMORY_REGION_ALLOCATOR_HPP
+#define TEACHOS_X86_64_MEMORY_REGION_ALLOCATOR_HPP
+
+#include "x86_64/memory/address.hpp"
+#include "x86_64/memory/frame.hpp"
+
+#include <multiboot2/information.hpp>
+
+#include <optional>
+#include <utility>
+
+namespace teachos::x86_64::memory
+{
+ /**
+ * @brief Allocates memory linearly using memory areas read from the multiboot2 information pointer and leaks any
+ * deallocated frames.
+ */
+ struct region_allocator
+ {
+ struct memory_information
+ {
+ std::pair<physical_address, physical_address> image_range;
+ std::pair<physical_address, physical_address> mbi_range;
+ multiboot2::memory_map memory_map;
+ };
+
+ /**
+ * @brief Constructor.
+ *
+ * @param mem_info Structure containing all relevant information to map and allocate memory.
+ */
+ explicit region_allocator(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<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 allocated in the first place.
+ *
+ * @param physical_frame Previously allocated physical_frame that should be deallocated.
+ */
+ auto deallocate_frame(frame const & physical_frame) -> void;
+
+ private:
+ /**
+ * @brief Find the next memory area and write it into current_area.
+ */
+ auto choose_next_area() -> void;
+
+ frame m_next_frame; ///< The physical_frame after the last allocated one.
+ std::optional<multiboot2::memory_map::region> m_current_region; ///< The memory region currently allocated from
+ multiboot2::memory_map m_memory_map; ///< The boot loader supplied memory map.
+ frame const m_kernel_start; ///< The start address of the kernel code in memory.
+ frame const m_kernel_end; ///< The end address of the kernel code in memory.
+ frame const m_multiboot_start; ///< The start address of the multiboot code in memory.
+ frame const m_multiboot_end; ///< The end address of the multiboot code in memory.
+ };
+
+} // namespace teachos::x86_64::memory
+
+#endif // TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_AREA_FRAME_ALLOCATOR_HPP