diff options
Diffstat (limited to 'arch/x86_64/include')
| -rw-r--r-- | arch/x86_64/include/arch/memory/frame_allocator.hpp | 122 |
1 files changed, 70 insertions, 52 deletions
diff --git a/arch/x86_64/include/arch/memory/frame_allocator.hpp b/arch/x86_64/include/arch/memory/frame_allocator.hpp index fa22ce5..1fd1f08 100644 --- a/arch/x86_64/include/arch/memory/frame_allocator.hpp +++ b/arch/x86_64/include/arch/memory/frame_allocator.hpp @@ -10,7 +10,7 @@ namespace teachos::arch::memory { namespace { - const std::size_t PAGE_FRAME_SIZE = 4096U; + constexpr std::size_t PAGE_FRAME_SIZE = 4096U; ///< Default page size of x86_84 is always 4KiB } /** @@ -18,18 +18,12 @@ namespace teachos::arch::memory */ struct frame { - std::size_t frame_number; ///< Index number of the current frame, used to distinguish it from other frames - /** * @brief Constructor * * @param frame_number Index number that should be assigned to this frame */ - frame(std::size_t frame_number) - : frame_number(frame_number) - { - // Nothing to do - } + frame(std::size_t frame_number); /** * @brief Returns the frame the given address is contained in @@ -37,7 +31,7 @@ namespace teachos::arch::memory * @param address Address we want to get the corresponding frame for * @return Frame the given address is contained in */ - static auto containing_address(std::size_t address) -> frame { return frame{address / PAGE_FRAME_SIZE}; } + static auto containing_address(std::size_t address) -> frame; /** * @brief Defaulted equals operator @@ -48,6 +42,8 @@ namespace teachos::arch::memory * @brief Defaulted three-way comparsion operator */ constexpr auto operator<=>(const frame & other) const -> std::partial_ordering = default; + + std::size_t frame_number; ///< Index number of the current frame, used to distinguish it from other frames }; template<typename T> @@ -57,36 +53,48 @@ namespace teachos::arch::memory }; /** - * @brief Iterator for memory areas + * @brief Iterator for memory areas. */ - class memory_area_iterator + struct memory_area_iterator { - memory_area * ptr; + /** + * @brief Constructor + * + * @param p Underlying address the iterator should point too, ensure to not pass an invalid pointer + */ + explicit memory_area_iterator(memory_area * p); - public: - std::size_t begin; - std::size_t end; + /** + * @brief Dereferences the initally given pointer to its value. + * + * @return Reference to the value + */ + memory_area & operator*() const; - explicit memory_area_iterator(memory_area * p) - : ptr(p) - { - } + /** + * @brief Post increment operator. Returns a copy of the value + * + * @return Copy of the incremented underlying address + */ + memory_area_iterator operator++(int); - memory_area & operator*() const { return *ptr; } - memory_area_iterator & operator++() - { - ++ptr; - return *this; - } + /** + * @brief Pre increment operator. Returns a reference to the changed value + * + * @return Reference to the incremented underlying address + */ + memory_area_iterator & operator++(); - memory_area_iterator operator++(int) - { - memory_area_iterator temp = *this; - ++(*this); - return temp; - } + /** + * @brief Defaulted comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to + * @return Whether poith iterators point to the same underlying address in memory + */ + bool operator==(memory_area_iterator const & other) const = default; - bool operator==(const memory_area_iterator & other) const { return ptr == other.ptr; } + private: + memory_area * ptr; ///< Underlying address the iterator is currently pointing too }; /** @@ -94,18 +102,6 @@ namespace teachos::arch::memory */ struct area_frame_allocator { - frame next_free_frame{0}; //!< The frame after the last allocated one - std::optional<memory_area> current_area{std::nullopt}; //!< The current memory area - memory_area * areas; //!< Pointer to the first element 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 - - private: - uint8_t N; - - public: /** * @brief Constructor * @@ -114,15 +110,16 @@ namespace teachos::arch::memory * @param multiboot_start Start address of the multiboot code in memory * @param multiboot_end End address of the multiboot code in memory * @param memory_areas Pointer to the first element of all memory areas + * @param area_count Amount of total entries in the memory_areas array */ area_frame_allocator(std::size_t kernel_start, std::size_t kernel_end, std::size_t multiboot_start, std::size_t multiboot_end, memory_area * memory_areas, uint8_t area_count) - : areas(memory_areas) - , kernel_start(frame{kernel_start}) - , kernel_end(frame{kernel_end}) - , multiboot_start(frame{multiboot_start}) - , multiboot_end(frame{multiboot_end}) - , N(area_count) + : area_begin(memory_areas) + , area_end(memory_areas + area_count) + , kernel_start(frame::containing_address(kernel_start)) + , kernel_end(frame::containing_address(kernel_end)) + , multiboot_start(frame::containing_address(multiboot_start)) + , multiboot_end(frame::containing_address(multiboot_end)) { choose_next_area(); } @@ -146,15 +143,36 @@ namespace teachos::arch::memory */ auto deallocate_frame(frame frame) -> void; - memory_area_iterator begin() { return memory_area_iterator(areas); } + /** + * @brief Returns the iterator pointing to the first element of the memory area. + * Allows using this class in the for each loop, because it follows the InputIterator template scheme + * + * @return Iterator pointing to first element of the memory area + */ + auto begin() -> memory_area_iterator; - memory_area_iterator end() { return memory_area_iterator(areas + N); } + /** + * @brief Returns the iterator pointing to one past the last element of the memory area. + * Allows using this class in the for each loop, because it follows the InputIterator template scheme + * + * @return Iterator pointing to one past the last element of the memory area + */ + auto end() -> memory_area_iterator; private: /** * @brief Find the next memory area and write it into current_area */ auto choose_next_area() -> void; + + frame next_free_frame{0}; ///< The frame after the last allocated one + std::optional<memory_area> current_area{std::nullopt}; ///< The current memory area + memory_area_iterator area_begin; ///< Pointer to the first element of all memory areas + memory_area_iterator area_end; ///< Pointer to one pas the last element of all memory areas + frame const kernel_start; ///< The start address of the kernel code in memory + frame const kernel_end; ///< The end address of the kernel code in memory + frame const multiboot_start; ///< The start address of the multiboot code in memory + frame const multiboot_end; ///< The end address of the multiboot code in memory }; } // namespace teachos::arch::memory |
