aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/include
diff options
context:
space:
mode:
authorFabian Imhof <fabian.imhof@ost.ch>2024-10-08 09:51:26 +0000
committerFabian Imhof <fabian.imhof@ost.ch>2024-10-08 09:51:26 +0000
commit8773024d1b4e756fe5d3494479247c64c7ad8491 (patch)
tree4d3dcf47b082f717b1de17ff48613f32fca15c86 /arch/x86_64/include
parent78153377d8a964d6b7290d966e5c1d30369abc2c (diff)
downloadteachos-8773024d1b4e756fe5d3494479247c64c7ad8491.tar.xz
teachos-8773024d1b4e756fe5d3494479247c64c7ad8491.zip
begin implementing frame allocator
Diffstat (limited to 'arch/x86_64/include')
-rw-r--r--arch/x86_64/include/arch/memory/frame_allocator.hpp72
1 files changed, 57 insertions, 15 deletions
diff --git a/arch/x86_64/include/arch/memory/frame_allocator.hpp b/arch/x86_64/include/arch/memory/frame_allocator.hpp
index 8dee848..35d7360 100644
--- a/arch/x86_64/include/arch/memory/frame_allocator.hpp
+++ b/arch/x86_64/include/arch/memory/frame_allocator.hpp
@@ -1,6 +1,7 @@
#ifndef TEACHOS_ARCH_X86_64_MEMORY_FRAME_HPP
#define TEACHOS_ARCH_X86_64_MEMORY_FRAME_HPP
+#include "multiboot.hpp"
#include <cstddef>
#include <optional>
@@ -8,20 +9,26 @@ namespace teachos::arch::memory
{
namespace
{
- const size_t PAGE_FRAME_SIZE = 4096U;
+ const std::size_t PAGE_FRAME_SIZE = 4096U;
}
struct frame
{
- size_t frame_number;
+ std::size_t frame_number;
- frame(size_t frame_number)
+ frame(std::size_t frame_number)
: frame_number(frame_number)
{
// Nothing to do
}
- auto containing_address(size_t address) -> frame { return frame{address / PAGE_FRAME_SIZE}; }
+ static auto containing_address(std::size_t address) -> frame { return frame{address / PAGE_FRAME_SIZE}; }
+
+ constexpr bool operator==(const frame & other) const noexcept { return frame_number == other.frame_number; }
+ constexpr bool operator>(const frame & other) const noexcept { return frame_number > other.frame_number; }
+ constexpr bool operator<(const frame & other) const noexcept { return frame_number < other.frame_number; }
+ constexpr bool operator>=(const frame & other) const noexcept { return frame_number >= other.frame_number; }
+ constexpr bool operator<=(const frame & other) const noexcept { return frame_number <= other.frame_number; }
};
struct frame_allocator
@@ -30,18 +37,53 @@ namespace teachos::arch::memory
virtual auto deallocate_frame(frame frame) -> void = 0;
};
- struct area_frame_allocator : public frame_allocator
+ // TODO: FIX CONCEPT USAGE
+ // template<typename T>
+ // concept FrameAllocator = requires(T t) {
+ // { t.allocate_frame() } -> std::optional<frame>;
+ // { t.deallocate_frame() } -> void;
+ // };
+
+ // template<FrameAllocator T>
+ struct area_frame_allocator : frame_allocator
{
- frame next_free_frame;
- // std::optional<memory_area> current_area;
- // memory_area * areas;
- frame kernel_start;
- frame kernel_end;
- frame multiboot_start;
- frame multiboot_end;
-
- auto allocate_frame() -> std::optional<frame> override;
- auto deallocate_frame(frame frame) -> void override;
+ frame next_free_frame{0}; //!< The frame after the last allocated one
+ std::optional<arch::memory::memory_area> current_area{std::nullopt}; //!< The current memory area
+ arch::memory::memory_area * areas; //!< A list of all memory areas
+ frame kernel_start; //!< The start address of the kernel code in memory
+ frame kernel_end; //!< The end address of the kernel code in memory
+ frame multiboot_start; //!< The start address of the multiboot code in memory
+ frame multiboot_end; //!< The end address of the multiboot code in memory
+
+ area_frame_allocator(std::size_t kernel_start, std::size_t kernel_end, std::size_t multiboot_start,
+ std::size_t multiboot_end, arch::memory::memory_area * memory_areas)
+ : kernel_start(frame{kernel_start})
+ , kernel_end(frame{kernel_end})
+ , multiboot_start(frame{multiboot_start})
+ , multiboot_end(frame{multiboot_end})
+ , areas(memory_areas)
+ {
+ choose_next_area();
+ }
+
+ /**
+ * @brief Allocate memory be finding and returning a free frame
+ *
+ * The frame allocation executes multiple checks before returning
+ * the 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 frame
+ */
+ auto allocate_frame() -> std::optional<frame>;
+ auto deallocate_frame(frame frame) -> void;
+
+ private:
+ /**
+ * @brief Find the next memory area and write it into current_area
+ */
+ auto choose_next_area() -> void;
};
} // namespace teachos::arch::memory