From 2b8e6e7e10f084a9a9ba5c0b79a041f4d1ac459b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Sat, 15 Mar 2025 11:29:26 +0000 Subject: implement loading of gdtr register --- CMakeLists.txt | 8 +- arch/x86_64/CMakeLists.txt | 8 +- .../descriptor_table/access_byte.hpp | 67 +++++--- .../descriptor_table/gdt_flags.hpp | 25 ++- .../global_descriptor_table_pointer.hpp | 22 ++- .../descriptor_table/segment_descriptor.hpp | 16 +- .../descriptor_table/type_field.hpp | 84 --------- arch/x86_64/include/arch/kernel/cpu/lgdt.hpp | 11 +- .../arch/memory/allocator/physical_frame.hpp | 6 +- .../arch/memory/heap/linked_list_allocator.hpp | 4 +- .../arch/memory/multiboot/elf_symbols_section.hpp | 6 +- .../include/arch/memory/multiboot/memory_map.hpp | 6 +- .../include/arch/memory/paging/virtual_page.hpp | 2 +- arch/x86_64/include/arch/shared/container.hpp | 83 --------- .../arch/shared/contiguous_pointer_iterator.hpp | 190 --------------------- .../include/arch/shared/forward_value_iterator.hpp | 110 ------------ arch/x86_64/include/arch/shared/mutex.hpp | 57 ------- arch/x86_64/include/arch/stl/container.hpp | 83 +++++++++ .../arch/stl/contiguous_pointer_iterator.hpp | 190 +++++++++++++++++++++ .../include/arch/stl/forward_value_iterator.hpp | 110 ++++++++++++ arch/x86_64/include/arch/stl/mutex.hpp | 57 +++++++ .../descriptor_table/access_byte.cpp | 10 +- .../descriptor_table/gdt_flags.cpp | 14 +- .../descriptor_table/global_descriptor_table.cpp | 40 +++-- .../global_descriptor_table_pointer.cpp | 12 ++ .../descriptor_table/segment_descriptor.cpp | 17 +- .../descriptor_table/type_field.cpp | 12 -- arch/x86_64/src/kernel/cpu/lgdt.cpp | 13 +- arch/x86_64/src/kernel/cpu/ss.cpp | 8 +- arch/x86_64/src/kernel/main.cpp | 13 +- .../src/memory/heap/linked_list_allocator.cpp | 2 +- arch/x86_64/src/shared/mutex.cpp | 16 -- arch/x86_64/src/stl/mutex.cpp | 16 ++ 33 files changed, 643 insertions(+), 675 deletions(-) delete mode 100644 arch/x86_64/include/arch/context_switching/descriptor_table/type_field.hpp delete mode 100644 arch/x86_64/include/arch/shared/container.hpp delete mode 100644 arch/x86_64/include/arch/shared/contiguous_pointer_iterator.hpp delete mode 100644 arch/x86_64/include/arch/shared/forward_value_iterator.hpp delete mode 100644 arch/x86_64/include/arch/shared/mutex.hpp create mode 100644 arch/x86_64/include/arch/stl/container.hpp create mode 100644 arch/x86_64/include/arch/stl/contiguous_pointer_iterator.hpp create mode 100644 arch/x86_64/include/arch/stl/forward_value_iterator.hpp create mode 100644 arch/x86_64/include/arch/stl/mutex.hpp create mode 100644 arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table_pointer.cpp delete mode 100644 arch/x86_64/src/context_switching/descriptor_table/type_field.cpp delete mode 100644 arch/x86_64/src/shared/mutex.cpp create mode 100644 arch/x86_64/src/stl/mutex.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index daf87b8..c895618 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,11 +123,11 @@ add_library("_context" OBJECT) add_library("teachos::context_switching" ALIAS "_context") #[============================================================================[ -# The Shared Library +# The Context switching Library #]============================================================================] -add_library("_shared" OBJECT) -add_library("teachos::shared" ALIAS "_shared") +add_library("_stl" OBJECT) +add_library("teachos::stl" ALIAS "_stl") #[============================================================================[ # The Kernel @@ -143,7 +143,7 @@ target_link_libraries("_kernel" PRIVATE "teachos::video" "teachos::memory" "teachos::exception" - "teachos::shared" + "teachos::stl" "teachos::context_switching" ) diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 53339d2..912daf6 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -65,11 +65,11 @@ target_sources("_memory" PRIVATE ) #[============================================================================[ -# The Shared Library +# The STL Library #]============================================================================] -target_sources("_shared" PRIVATE - "src/shared/mutex.cpp" +target_sources("_stl" PRIVATE + "src/stl/mutex.cpp" ) #[============================================================================[ @@ -91,8 +91,8 @@ target_sources("_context" PRIVATE "src/context_switching/descriptor_table/access_byte.cpp" "src/context_switching/descriptor_table/gdt_flags.cpp" "src/context_switching/descriptor_table/global_descriptor_table.cpp" + "src/context_switching/descriptor_table/global_descriptor_table_pointer.cpp" "src/context_switching/descriptor_table/segment_descriptor.cpp" - "src/context_switching/descriptor_table/type_field.cpp" ) #[============================================================================[ diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/access_byte.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/access_byte.hpp index dc4de03..bafce8d 100644 --- a/arch/x86_64/include/arch/context_switching/descriptor_table/access_byte.hpp +++ b/arch/x86_64/include/arch/context_switching/descriptor_table/access_byte.hpp @@ -2,9 +2,8 @@ #ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_ACCESS_BYTE_HPP #define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_ACCESS_BYTE_HPP -#include "arch/context_switching/descriptor_table/type_field.hpp" - #include +#include namespace teachos::arch::context_switching::descriptor_table { @@ -12,24 +11,49 @@ namespace teachos::arch::context_switching::descriptor_table * @brief Defines helper function for all states that the access byte field of a segment descriptor can * have. */ - struct access_byte + struct [[gnu::packed]] access_byte { /** * @brief Possible set bits in our underlying std::bitset and the meaning when they are set. */ enum bitset : uint8_t { - CODE_OR_DATA_SEGMENT = 1U << 0U, ///< Defines a system segment (if 0) or a code/data segment (if 1). - ACCESS_LEVEL_KERNEL = 0, ///< Highest privileged level used by the kernel to allow for full access of resources. + ACCESSED = + 1U + << 0U, ///< Whether the segment has been accessed since the last time the operating system has cleared the + ///< flag. If enabled it has been accessed, otherwise it has not been accessed since the last clear. + WRITABLE = 1U << 1U, ///< Indicates if the data segment is writable or not. If enabled the code segment allows + ///< read and write access, otherwise only read access is possible. + READABLE = 1U << 1U, ///< Indicates if the code segment is readable or not. If enabled the code segment allows + ///< read and execute access, otherwise only executable access is possible. + CONFORMING = + 1U << 2U, ///< Indicates if the code is allowed to be executed by different access levels + ///< (higher or lower) in code segments. If enabled the code segment allows access, otherwise + ///< access from different privilege levels with throw a General-Protectione exception. + EXPAND_DOWN = 1U << 2U, ///< Indicates if the expansion direction is up or down in data segments. If enabled the + ///< data segment expands downwards, otherwise it expands upwards. + CODE_SEGMENT = 1U << 3U, ///< Further defines the actual type of the segment. If enabled this segment is a code + ///< segment, otherwise its a data segment. + LOCAL_DESCRIPTOR_TABLE = 2, ///< The actual type of sytem segment is a local descriptor table. + TASK_STATE_SEGMENT_AVAILABLE = + 9, ///< The actual type of sytem segment is a task state segment that is still available. + TASK_STATE_SEGMENT_BUSY = 11, ///< The actual type of sytem segment is a task state segment that is currently in + ///< use and therefore busy. + CALL_GATE = 11, ///< The actual type of sytem segment is a call gate. + INTERRUPT_GATE = 14, ///< The actual type of sytem segment is a interrupt gate. + TRAP_GATE = 15, ///< The actual type of sytem segment is a trap gate. + CODE_OR_DATA_SEGMENT = 1U << 4U, ///< Defines a system segment (if 0) or a code/data segment (if 1). + ACCESS_LEVEL_KERNEL = + 0U << 4U, ///< Highest privileged level used by the kernel to allow for full access of resources. ACCESS_LEVEL_ADMIN = - 2, ///< Restricts access to own application and thoose of lower privilege. Should only be used if more - ///< than two privilege levels are required, otherwise using Level 3 and Level 0 is recommended. + 2U << 4U, ///< Restricts access to own application and thoose of lower privilege. Should only be used if more + ///< than two privilege levels are required, otherwise using Level 3 and Level 0 is recommended. ACCESS_LEVEL_PRIVILEGED_USER = - 4, ///< Restricts access to own application and thoose of lower privilege. Should only be used if more than - ///< two privilege levels are required, otherwise using Level 3 and Level 0 is recommended. - ACCESS_LEVEL_USER = 6, ///< Restricts access to only application and their specific memory. - PRESENT = 1U << 3U, ///< Present bit; Allows an entry to refer to a valid segment. - ///< Must be set (1) for any valid segment. + 4U << 4U, ///< Restricts access to own application and thoose of lower privilege. Should only be used if more + ///< than two privilege levels are required, otherwise using Level 3 and Level 0 is recommended. + ACCESS_LEVEL_USER = 6U << 4U, ///< Restricts access to only application and their specific memory. + PRESENT = 1U << 3U << 4U, ///< Present bit; Allows an entry to refer to a valid segment. + ///< Must be set (1) for any valid segment. }; /** @@ -40,10 +64,11 @@ namespace teachos::arch::context_switching::descriptor_table /** * @brief Constructor. * - * @param flags Left-most four bits of the access_byte. - * @param type_field Right-most four bits of the access_byte representing the type_field. + * @param flags Allows to set flags for the access byte field using the unscoped enum contained in this class, used + * to allow for direct integer conversion. This value is saved and can later be used to check whether certain flags + * are enabled or not using contains_flags method. */ - access_byte(uint8_t flags, uint8_t type_field); + access_byte(uint8_t flags); /** * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset. @@ -54,14 +79,7 @@ namespace teachos::arch::context_switching::descriptor_table * @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<4U> other) const -> bool; - - /** - * @brief Returns the type field of the access byte. - * - * @return Copy of the underlying type field bits. - */ - auto get_type_field() const -> type_field; + auto contains_flags(std::bitset<8U> other) const -> bool; /** * @brief Allows to compare the underlying std::bitset of two instances. @@ -72,8 +90,7 @@ namespace teachos::arch::context_switching::descriptor_table auto operator==(access_byte const & other) const -> bool = default; private: - std::bitset<4U> _flags = {}; ///< Underlying bitset used to read the flags from. - type_field _type = {}; ///< Field specifying the type of the segment descriptor and its settings. + uint8_t _flags = {}; ///< Underlying bitset used to read the flags from. }; } // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/gdt_flags.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/gdt_flags.hpp index f27284e..11f5dd4 100644 --- a/arch/x86_64/include/arch/context_switching/descriptor_table/gdt_flags.hpp +++ b/arch/x86_64/include/arch/context_switching/descriptor_table/gdt_flags.hpp @@ -11,7 +11,7 @@ namespace teachos::arch::context_switching::descriptor_table * @brief Defines helper function for all states that the flags field of a segment descriptor can * have. */ - struct gdt_flags + struct [[gnu::packed]] gdt_flags { /** * @brief Possible set bits in our underlying std::bitset and the meaning when they are set. @@ -40,11 +40,14 @@ namespace teachos::arch::context_switching::descriptor_table /** * @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. Only the rightmost 3 bit of the value will actually be - * converted into the std::bitset, because the leftmost 4 bit are irrelevant and the 4th bit is reserved. + * @param flags Allows to set flags for the flags field using the unscoped enum contained in this class, used to + * allow for direct integer conversion. This value is saved and can later be used to check whether certain flags are + * enabled or not using contains_flags method. + * @param limit Does not necessarily make sense in the gdt flags type, but because the flags alone are only 4 bit + * the type would still require the space for a complete bit. Therefore the 4 bit segment limit field before the + * flags field is included in this type to ensure we actually contain 8 bit of data. */ - gdt_flags(uint8_t flags); + gdt_flags(uint8_t flags, std::bitset<20U> limit); /** * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset. @@ -57,6 +60,15 @@ namespace teachos::arch::context_switching::descriptor_table */ auto contains_flags(std::bitset<4U> other) const -> bool; + /** + * @brief Get part of the segment limit that is saved in the gdt flags. This does not necessarily make sense in this + * object, but it has to be included here because a struct can not be smaller than a full byte. Therefore we include + * the 4 bit segment limit field so that it results in a compelte byte with the addtional 4 bit of gdt flags. + * + * @return 4-bit limit segment + */ + auto get_limit() const -> std::bitset<4U>; + /** * @brief Allows to compare the underlying std::bitset of two instances. * @@ -66,7 +78,8 @@ namespace teachos::arch::context_switching::descriptor_table auto operator==(gdt_flags const & other) const -> bool = default; private: - std::bitset<4U> _flags = {}; ///< Underlying bitset used to read the flags from. + uint8_t _limit_2 : 4 = {}; + uint8_t _flags : 4 = {}; ///< Underlying bitset used to read the flags from. }; } // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp index d4febe1..ed17be3 100644 --- a/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp +++ b/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp @@ -16,10 +16,26 @@ namespace teachos::arch::context_switching::descriptor_table * This structure is used to store the base address and length of the GDT. * It is used when loading or modifying the GDT during context switching. */ - struct global_descriptor_table_pointer + struct [[gnu::packed]] global_descriptor_table_pointer { - std::size_t table_length; ///< The size of the GDT in bytes. - global_descriptor_table * address; ///< Pointer to the GDT base address. + /** + * @brief Default constructor. + */ + global_descriptor_table_pointer() = default; + + /** + * @brief Constructor. + */ + global_descriptor_table_pointer(uint16_t table_length, global_descriptor_table * address); + + /** + * @brief Defaulted three-way comparsion operator. + */ + auto operator<=>(global_descriptor_table_pointer const & other) const -> std::strong_ordering = default; + + private: + uint16_t table_length = {}; ///< The amount of segment descriptor entries in the global descriptor table - 1. + global_descriptor_table * address = {}; ///< Non-owning pointer to the GDT base address. }; } // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/segment_descriptor.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/segment_descriptor.hpp index 86b6c75..7106771 100644 --- a/arch/x86_64/include/arch/context_switching/descriptor_table/segment_descriptor.hpp +++ b/arch/x86_64/include/arch/context_switching/descriptor_table/segment_descriptor.hpp @@ -4,7 +4,6 @@ #include "arch/context_switching/descriptor_table/access_byte.hpp" #include "arch/context_switching/descriptor_table/gdt_flags.hpp" #include "arch/context_switching/descriptor_table/segment_descriptor_type.hpp" -#include "arch/context_switching/descriptor_table/type_field.hpp" namespace teachos::arch::context_switching::descriptor_table { @@ -14,7 +13,7 @@ namespace teachos::arch::context_switching::descriptor_table /** * @brief Defines helper function for all states and the actual data the segment descriptor can have. */ - struct segment_descriptor + struct [[gnu::packed]] segment_descriptor { /** * @brief Default Constructor. @@ -52,13 +51,12 @@ namespace teachos::arch::context_switching::descriptor_table private: // The order in private variables starts for the first variable being the rightmost bit. - uint16_t _limit_1 = {}; ///< First part of the limit field (0 - 15) - std::bitset<24U> _base_1 = {}; ///< First part of the base field (16 - 39) - access_byte _access = {}; ///< Access byte field (40 - 47) - std::bitset<4U> _limit_2 = {}; ///< Second part of the limit field (48 - 51) - gdt_flags _flag = {}; ///< Flags field (52 - 55) - std::bitset<40U> _base_2 = {}; ///< Second part of the base field (56 - 95) - uint32_t _reserved = {}; ///< Reserved field used to ensure this struct is 128 bits big (96 - 127) + uint16_t _limit_1 = {}; ///< First part of the limit field (0 - 15) + uint32_t _base_1 : 24 = {}; ///< First part of the base field (16 - 39) + access_byte _access = {}; ///< Access byte field (40 - 47) + gdt_flags _flag = {}; ///< Second part of the limit field + Flags field (48 - 55) + uint64_t _base_2 : 40 = {}; ///< Second part of the base field (56 - 95) + uint32_t _reserved = {}; ///< Reserved field used to ensure this struct is 128 bits big (96 - 127) }; } // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/type_field.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/type_field.hpp deleted file mode 100644 index 3822f9c..0000000 --- a/arch/x86_64/include/arch/context_switching/descriptor_table/type_field.hpp +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_TYPE_FIELD_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_TYPE_FIELD_HPP - -#include "arch/context_switching/descriptor_table/segment_descriptor_type.hpp" - -#include - -namespace teachos::arch::context_switching::descriptor_table -{ - /** - * @brief Defines helper function for all states that the flags field of a segment descriptor can - * have. - */ - struct type_field - { - /** - * @brief Possible set bits in our underlying std::bitset and the meaning when they are set. - */ - enum bitset : uint8_t - { - ACCESSED = - 1U - << 0U, ///< Whether the segment has been accessed since the last time the operating system has cleared the - ///< flag. If enabled it has been accessed, otherwise it has not been accessed since the last clear. - WRITABLE = 1U << 1U, ///< Indicates if the data segment is writable or not. If enabled the code segment allows - ///< read and write access, otherwise only read access is possible. - READABLE = 1U << 1U, ///< Indicates if the code segment is readable or not. If enabled the code segment allows - ///< read and execute access, otherwise only executable access is possible. - CONFORMING = - 1U << 2U, ///< Indicates if the code is allowed to be executed by different access levels - ///< (higher or lower) in code segments. If enabled the code segment allows access, otherwise - ///< access from different privilege levels with throw a General-Protectione exception. - EXPAND_DOWN = 1U << 2U, ///< Indicates if the expansion direction is up or down in data segments. If enabled the - ///< data segment expands downwards, otherwise it expands upwards. - CODE_SEGMENT = 1U << 3U, ///< Further defines the actual type of the segment. If enabled this segment is a code - ///< segment, otherwise its a data segment. - LOCAL_DESCRIPTOR_TABLE = 2, ///< The actual type of sytem segment is a local descriptor table. - TASK_STATE_SEGMENT_AVAILABLE = - 9, ///< The actual type of sytem segment is a task state segment that is still available. - TASK_STATE_SEGMENT_BUSY = 11, ///< The actual type of sytem segment is a task state segment that is currently in - ///< use and therefore busy. - CALL_GATE = 11, ///< The actual type of sytem segment is a call gate. - INTERRUPT_GATE = 14, ///< The actual type of sytem segment is a interrupt gate. - TRAP_GATE = 15 ///< The actual type of sytem segment is a trap gate. - }; - - /** - * @brief Default Constructor. - */ - type_field() = default; - - /** - * @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. - */ - type_field(uint8_t flags); - - /** - * @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<4U> 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==(type_field const & other) const -> bool = default; - - private: - std::bitset<4U> _flags = {}; ///< Underlying bitset used to read the flags from. - }; -} // namespace teachos::arch::context_switching::descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_TYPE_FIELD_HPP diff --git a/arch/x86_64/include/arch/kernel/cpu/lgdt.hpp b/arch/x86_64/include/arch/kernel/cpu/lgdt.hpp index 633d460..85e2949 100644 --- a/arch/x86_64/include/arch/kernel/cpu/lgdt.hpp +++ b/arch/x86_64/include/arch/kernel/cpu/lgdt.hpp @@ -8,10 +8,19 @@ namespace teachos::arch::kernel::cpu { + + /** + * @brief Returns the value in the GDTR register. + * + * @return Value of GDTR register. + */ + auto store_global_descriptor_table() -> context_switching::descriptor_table::global_descriptor_table_pointer; + /** * @brief Loads the global_descriptor_table_pointer into the global descriptor table register (GDTR). */ - auto load_global_descriptor_table(context_switching::descriptor_table::global_descriptor_table_pointer gdt_pointer) + auto + load_global_descriptor_table(context_switching::descriptor_table::global_descriptor_table_pointer const & gdt_pointer) -> void; } // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp b/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp index 7f04042..7ea5517 100644 --- a/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp +++ b/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp @@ -1,8 +1,8 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_PHYSICAL_FRAME_HPP #define TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_PHYSICAL_FRAME_HPP -#include "arch/shared/container.hpp" -#include "arch/shared/forward_value_iterator.hpp" +#include "arch/stl/container.hpp" +#include "arch/stl/forward_value_iterator.hpp" #include #include @@ -79,7 +79,7 @@ namespace teachos::arch::memory::allocator {}; ///< Index number of the current physical frame, used to distinguish it from other frames. }; - typedef shared::container> frame_container; + typedef stl::container> frame_container; } // namespace teachos::arch::memory::allocator diff --git a/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp index df9e370..da3c8ff 100644 --- a/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp @@ -3,7 +3,7 @@ #include "arch/memory/heap/heap_allocator.hpp" #include "arch/memory/heap/memory_block.hpp" -#include "arch/shared/mutex.hpp" +#include "arch/stl/mutex.hpp" namespace teachos::arch::memory::heap { @@ -114,7 +114,7 @@ namespace teachos::arch::memory::heap std::size_t heap_start; ///< Start of the allocatable heap area. std::size_t heap_end; ///< End of the allocatable heap area. memory_block * first; ///< First free entry in our memory. - shared::mutex mutex; ///< Mutex to ensure only one thread calls allocate or deallocate at once. + stl::mutex mutex; ///< Mutex to ensure only one thread calls allocate or deallocate at once. }; extern linked_list_allocator kernel_heap; diff --git a/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp b/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp index e8f6b0a..4c7470b 100644 --- a/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp +++ b/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp @@ -2,8 +2,8 @@ #define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP #include "arch/memory/multiboot/info.hpp" -#include "arch/shared/container.hpp" -#include "arch/shared/contiguous_pointer_iterator.hpp" +#include "arch/stl/container.hpp" +#include "arch/stl/contiguous_pointer_iterator.hpp" #include #include @@ -162,7 +162,7 @@ namespace teachos::arch::memory::multiboot ///< contained in the section, to ensure byte alignment is actually 4 byte. }; - typedef shared::container> elf_section_header_container; + typedef stl::container> elf_section_header_container; } // namespace teachos::arch::memory::multiboot diff --git a/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp b/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp index c28c986..cc8db8c 100644 --- a/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp +++ b/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp @@ -2,8 +2,8 @@ #define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_MEMORY_MAP_HPP #include "arch/memory/multiboot/info.hpp" -#include "arch/shared/container.hpp" -#include "arch/shared/contiguous_pointer_iterator.hpp" +#include "arch/stl/container.hpp" +#include "arch/stl/contiguous_pointer_iterator.hpp" #include @@ -46,7 +46,7 @@ namespace teachos::arch::memory::multiboot struct memory_area entries; ///< Specific memory regions. }; - typedef shared::container> memory_area_container; + typedef stl::container> memory_area_container; } // namespace teachos::arch::memory::multiboot diff --git a/arch/x86_64/include/arch/memory/paging/virtual_page.hpp b/arch/x86_64/include/arch/memory/paging/virtual_page.hpp index d820e82..d9164a0 100644 --- a/arch/x86_64/include/arch/memory/paging/virtual_page.hpp +++ b/arch/x86_64/include/arch/memory/paging/virtual_page.hpp @@ -84,7 +84,7 @@ namespace teachos::arch::memory::paging {}; ///< Index number of the current virtual page, used to distinguish it from other pages. }; - typedef shared::container> page_container; + typedef stl::container> page_container; } // namespace teachos::arch::memory::paging diff --git a/arch/x86_64/include/arch/shared/container.hpp b/arch/x86_64/include/arch/shared/container.hpp deleted file mode 100644 index f2fd1dc..0000000 --- a/arch/x86_64/include/arch/shared/container.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP -#define TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP - -#include - -namespace teachos::arch::shared -{ - /** - * @brief Minimal iterator concept required for usage in container - */ - template - concept Iterator = std::forward_iterator; - - /** - * @brief Read-only container for given template type, that allow to easily use this container instance in C++20 - * ranges calls. - * - * @tparam T Iterator the container uses to signal the start and end of it's data, has to atleast be a simple forward - * iterator. - */ - template - struct container - { - using iterator = T; ///< Iterators used by this container. - using size_type = std::size_t; ///< Maximum size of this container. - - /** - * @brief Defaulted constructor. - */ - container() = default; - - /** - * @brief Constructor. - * - * @param begin Iterator containing non-owning pointer to the first element of all memory areas. - * @param end Iterator pointing to one past the last element of all memory areas. - */ - container(iterator begin, iterator end) - : begin_itr(begin) - , end_itr(end) - { - // Nothing to do - } - - /** - * @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() const -> iterator { return begin_itr; } - - /** - * @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() const -> iterator { return end_itr; } - - /** - * @brief Calculates the size of this container, simply subtracts the iterator pointing to the first element by the - * last. - * - * @return Actual size of this container. - */ - auto size() const -> size_type { return std::distance(begin(), end()); } - - /** - * @brief Calcualtes the size and returns true if the size is 0 and the container therefore emtpy. - * - * @return Whether the container is empty, size being 0 or not - */ - auto empty() const -> bool { return size() == 0; } - - private: - iterator begin_itr = {}; ///< Pointer to the first element of the given template type. - iterator end_itr = {}; ///< Pointer to one pas the last element of the given template type. - }; - -} // namespace teachos::arch::shared - -#endif // TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP diff --git a/arch/x86_64/include/arch/shared/contiguous_pointer_iterator.hpp b/arch/x86_64/include/arch/shared/contiguous_pointer_iterator.hpp deleted file mode 100644 index e2520dc..0000000 --- a/arch/x86_64/include/arch/shared/contiguous_pointer_iterator.hpp +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_SHARED_CONTIGUOUS_POINTER_ITERATOR_HPP -#define TEACHOS_ARCH_X86_64_SHARED_CONTIGUOUS_POINTER_ITERATOR_HPP - -#include - -namespace teachos::arch::shared -{ - /** - * @brief Generic contiguous iterator for given template type. Allows to easily use this iterator instance in - * algorithm calls. - * - * @note Allows any value that is contained in an array in memory, which is a block of contiguous memory. This is the - * case because we assume we can simply increment or decrement the pointer address to get the next valid instance of - * the given value type. - * - * @tparam T Value the iterator points too. - */ - template - struct contiguous_pointer_iterator - { - using iterator_category = std::contiguous_iterator_tag; ///< Iterator category of this type. - using difference_type = std::ptrdiff_t; ///< Type when diving one instance of this iterator by another. - using value_type = T; ///< Underlying value pointed to by this iterator. - using reference_type = value_type &; ///< Reference to value returned by dereference * operation. - using pointer_type = value_type *; ///< Pointer to value returned by arrow -> operation. - - /** - * @brief Defaulted constructor. - */ - contiguous_pointer_iterator() = default; - - /** - * @brief Constructor. - * - * @param p Underlying address the iterator should point too. - */ - explicit contiguous_pointer_iterator(value_type * p) - : ptr(p) - { - // Nothing to do - } - - /** - * @brief Dereferences the initally given pointer to its value. - * - * @return Reference to the value. - */ - auto operator*() const -> reference_type { return *ptr; } - - /** - * @brief Get underlying value, which is the intially passed pointer. - * - * @return Pointer to the underlying value passed intially. - */ - auto operator->() const -> pointer_type { return ptr; } - - /** - * @brief Pre decrement operator. Returns a reference to the changed address. - * - * @return Reference to the decremented underlying address. - */ - auto operator--() -> contiguous_pointer_iterator & - { - contiguous_pointer_iterator const old_value = *this; - ++ptr; - return old_value; - } - - /** - * @brief Pre increment operator. Returns a reference to the changed address. - * - * @return Reference to the incremented underlying address. - */ - auto operator++() -> contiguous_pointer_iterator & - { - ++ptr; - return *this; - } - - /** - * @brief Post decrement operator. Returns a copy of the address. - * - * @return Copy of the decremented underlying address. - */ - auto operator--(int) -> contiguous_pointer_iterator - { - auto const old_value = *this; - --ptr; - return old_value; - } - - /** - * @brief Post increment operator. Returns a copy of the address. - * - * @return Copy of the incremented underlying address. - */ - auto operator++(int) -> contiguous_pointer_iterator - { - auto const old_value = *this; - ++ptr; - return old_value; - } - - /** - * @brief Addition assignment operator. Returns a reference to the changed address. - * - * @param value Value we want to add to the underlying address. - * @return Reference to the changed underlying address. - */ - auto operator+=(difference_type value) -> contiguous_pointer_iterator & - { - ptr += value; - return *this; - } - - /** - * @brief Subtraction assignment operator. Returns a reference to the changed address. - * - * @param value Value we want to subtract from the underlying address. - * @return Reference to the changed underlying address. - */ - auto operator-=(difference_type value) -> contiguous_pointer_iterator & - { - ptr -= value; - return *this; - } - - /** - * @brief Addition operator. Returns the changed address. - * - * @param value Value we want to add to a copy of the underlying address. - * @return Copy of underlying address incremented by the given value. - */ - auto operator+(difference_type value) const -> contiguous_pointer_iterator - { - return contiguous_pointer_iterator{ptr + value}; - } - - /** - * @brief Subtraction operator. Returns the changed address. - * - * @param value Value we want to subtrcat from a copy of the underlying address. - * @return Copy of underlying address decremented by the given value. - */ - auto operator-(difference_type value) const -> contiguous_pointer_iterator - { - return contiguous_pointer_iterator{ptr - value}; - } - - /** - * @brief Subtraction operator. Returns the size difference between two iterators. - * - * @param other Other iterator we want to substract the underlying address with ours. - * @return Size difference between the underlying address of this instance and the given iterator. - */ - auto operator-(const contiguous_pointer_iterator & other) const -> difference_type { return ptr - other.ptr; } - - /** - * @brief Index operator overload. Returns a reference to the value at the given index. Simply returns the - * dereferenced underlying pointer incremented by the given index. - * - * @param index Index we want to access and get the value from. - * @return Reference to the value at the given index. - */ - auto operator[](difference_type index) const -> value_type & { return *(ptr + index); } - - /** - * @brief Defaulted comparsion operator. Simply compares the memory address of both iterators. - * - * @param other Other iterator to compare to. - * @return Whether both iterators point to the same underlying address in memory. - */ - auto operator==(contiguous_pointer_iterator const & other) const -> bool = default; - - /** - * @brief Defaulted threeway comparsion operator. Simply compares the memory address of both iterators. - * - * @param other Other iterator to compare to. - * @return Whether the given iterator is smaller or larger than this iterator. - */ - auto operator<=>(contiguous_pointer_iterator const & other) const -> std::strong_ordering = default; - - private: - pointer_type ptr = - {}; ///< Underlying value the iterator is currently pointing too and should increment or decrement. - }; - -} // namespace teachos::arch::shared - -#endif // TEACHOS_ARCH_X86_64_SHARED_CONTIGUOUS_POINTER_ITERATOR_HPP diff --git a/arch/x86_64/include/arch/shared/forward_value_iterator.hpp b/arch/x86_64/include/arch/shared/forward_value_iterator.hpp deleted file mode 100644 index c5dfc06..0000000 --- a/arch/x86_64/include/arch/shared/forward_value_iterator.hpp +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_SHARED_FORWARD_VALUE_ITERATOR_HPP -#define TEACHOS_ARCH_X86_64_SHARED_FORWARD_VALUE_ITERATOR_HPP - -#include - -namespace teachos::arch::shared -{ - /** - * @brief Concept for a type to have a post and prefix increment operator, that returns the correct type. - */ - template - concept Incrementable = requires(T t) { - { ++t } -> std::same_as; - { t++ } -> std::same_as; - }; - - /** - * @brief Iterable concept for the forward value iterator, meaning the type itself is incrementable and comparable. - */ - template - concept Iterable = std::regular && Incrementable; - - /** - * @brief Generic forward iterator for given template type. Allows to easily use this iterator - * instance in algorithm calls. - * - * @note Allows any value that itself can be incremented until we have reached the end, does not interact with the - * address of the value in any way. - * - * @tparam T Value the iterator contains. - */ - template - struct forward_value_iterator - { - using iterator_category = std::forward_iterator_tag; ///< Iterator category of this type. - using difference_type = std::ptrdiff_t; ///< Type when diving one instance of this iterator by another. - using value_type = T; ///< Underlying value contained by this iterator. - using const_reference_type = - value_type const &; ///< Constant reference to value returned by dereference * operation. - using const_pointer_type = value_type const *; ///< Constant pointer to value returned by arrow -> operation. - - /** - * @brief Defaulted constructor. - */ - forward_value_iterator() = default; - - /** - * @brief Constructor. - * - * @param value Underlying value the iterator contains. - */ - explicit forward_value_iterator(value_type value) - : value(value) - { - // Nothing to do - } - - /** - * @brief Returns the initally given value. - * - * @return Reference to the value. - */ - auto operator*() const -> const_reference_type { return value; } - - /** - * @brief Gets pointer to the underlying value passed intially. - * - * @return Pointer to the underlying value passed intially. - */ - auto operator->() const -> const_pointer_type { return &value; } - - /** - * @brief Pre increment operator. Returns a reference to the changed value. - * - * @return Reference to the incremented underlying value. - */ - auto operator++() -> forward_value_iterator & - { - ++value; - return *this; - } - - /** - * @brief Post increment operator. Returns a copy of the value. - * - * @return Copy of the incremented underlying value. - */ - auto operator++(int) -> forward_value_iterator - { - auto const old_value = *this; - ++value; - return old_value; - } - - /** - * @brief Defaulted comparsion operator. Simply compares the memory address of both iterators. - * - * @param other Other iterator to compare to. - * @return Whether both iterators point to the same underlying address in memory. - */ - auto operator==(forward_value_iterator const & other) const -> bool = default; - - private: - value_type value = - {}; ///< Underlying value the iterator is currently pointing too and should increment or decrement. - }; - -} // namespace teachos::arch::shared - -#endif // TEACHOS_ARCH_X86_64_SHARED_FORWARD_VALUE_ITERATOR_HPP diff --git a/arch/x86_64/include/arch/shared/mutex.hpp b/arch/x86_64/include/arch/shared/mutex.hpp deleted file mode 100644 index b18a8b3..0000000 --- a/arch/x86_64/include/arch/shared/mutex.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_SHARED_MUTEX_HPP -#define TEACHOS_ARCH_X86_64_SHARED_MUTEX_HPP - -#include - -namespace teachos::arch::shared -{ - /** - * @brief Custom mutex implementation, that simply wraps an atomic boolean to keep track if the mutex is already in - * use by another thread or not. - */ - struct mutex - { - /** - * @brief Defaulted constructor. - */ - mutex() = default; - - /** - * @brief Defaulted destructor. - */ - ~mutex() = default; - - /** - * @brief Deleted copy constructor. - */ - mutex(const mutex &) = delete; - - /** - * @brief Deleted assignment operator. - */ - mutex & operator=(const mutex &) = delete; - - /** - * @brief Lock the mutex (blocks for as long as it is not available). - */ - auto lock() -> void; - - /** - * @brief Try to lock the mutex (non-blocking). - * - * @return True if lock has been acquired and false otherwise. - */ - auto try_lock() -> bool; - - /** - * @brief Unlock the mutex. - */ - auto unlock() -> void; - - private: - std::atomic locked = {false}; // Atomic boolean to track if mutex is locked or not. - }; - -} // namespace teachos::arch::shared - -#endif // TEACHOS_ARCH_X86_64_SHARED_MUTEX_HPP diff --git a/arch/x86_64/include/arch/stl/container.hpp b/arch/x86_64/include/arch/stl/container.hpp new file mode 100644 index 0000000..b0f513b --- /dev/null +++ b/arch/x86_64/include/arch/stl/container.hpp @@ -0,0 +1,83 @@ +#ifndef TEACHOS_ARCH_X86_64_STL_CONTAINER_HPP +#define TEACHOS_ARCH_X86_64_STL_CONTAINER_HPP + +#include + +namespace teachos::arch::stl +{ + /** + * @brief Minimal iterator concept required for usage in container + */ + template + concept Iterator = std::forward_iterator; + + /** + * @brief Read-only container for given template type, that allow to easily use this container instance in C++20 + * ranges calls. + * + * @tparam T Iterator the container uses to signal the start and end of it's data, has to atleast be a simple forward + * iterator. + */ + template + struct container + { + using iterator = T; ///< Iterators used by this container. + using size_type = std::size_t; ///< Maximum size of this container. + + /** + * @brief Defaulted constructor. + */ + container() = default; + + /** + * @brief Constructor. + * + * @param begin Iterator containing non-owning pointer to the first element of all memory areas. + * @param end Iterator pointing to one past the last element of all memory areas. + */ + container(iterator begin, iterator end) + : begin_itr(begin) + , end_itr(end) + { + // Nothing to do + } + + /** + * @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() const -> iterator { return begin_itr; } + + /** + * @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() const -> iterator { return end_itr; } + + /** + * @brief Calculates the size of this container, simply subtracts the iterator pointing to the first element by the + * last. + * + * @return Actual size of this container. + */ + auto size() const -> size_type { return std::distance(begin(), end()); } + + /** + * @brief Calcualtes the size and returns true if the size is 0 and the container therefore emtpy. + * + * @return Whether the container is empty, size being 0 or not + */ + auto empty() const -> bool { return size() == 0; } + + private: + iterator begin_itr = {}; ///< Pointer to the first element of the given template type. + iterator end_itr = {}; ///< Pointer to one pas the last element of the given template type. + }; + +} // namespace teachos::arch::stl + +#endif // TEACHOS_ARCH_X86_64_STL_CONTAINER_HPP diff --git a/arch/x86_64/include/arch/stl/contiguous_pointer_iterator.hpp b/arch/x86_64/include/arch/stl/contiguous_pointer_iterator.hpp new file mode 100644 index 0000000..d15d2e2 --- /dev/null +++ b/arch/x86_64/include/arch/stl/contiguous_pointer_iterator.hpp @@ -0,0 +1,190 @@ +#ifndef TEACHOS_ARCH_X86_64_STL_CONTIGUOUS_POINTER_ITERATOR_HPP +#define TEACHOS_ARCH_X86_64_STL_CONTIGUOUS_POINTER_ITERATOR_HPP + +#include + +namespace teachos::arch::stl +{ + /** + * @brief Generic contiguous iterator for given template type. Allows to easily use this iterator instance in + * algorithm calls. + * + * @note Allows any value that is contained in an array in memory, which is a block of contiguous memory. This is the + * case because we assume we can simply increment or decrement the pointer address to get the next valid instance of + * the given value type. + * + * @tparam T Value the iterator points too. + */ + template + struct contiguous_pointer_iterator + { + using iterator_category = std::contiguous_iterator_tag; ///< Iterator category of this type. + using difference_type = std::ptrdiff_t; ///< Type when diving one instance of this iterator by another. + using value_type = T; ///< Underlying value pointed to by this iterator. + using reference_type = value_type &; ///< Reference to value returned by dereference * operation. + using pointer_type = value_type *; ///< Pointer to value returned by arrow -> operation. + + /** + * @brief Defaulted constructor. + */ + contiguous_pointer_iterator() = default; + + /** + * @brief Constructor. + * + * @param p Underlying address the iterator should point too. + */ + explicit contiguous_pointer_iterator(value_type * p) + : ptr(p) + { + // Nothing to do + } + + /** + * @brief Dereferences the initally given pointer to its value. + * + * @return Reference to the value. + */ + auto operator*() const -> reference_type { return *ptr; } + + /** + * @brief Get underlying value, which is the intially passed pointer. + * + * @return Pointer to the underlying value passed intially. + */ + auto operator->() const -> pointer_type { return ptr; } + + /** + * @brief Pre decrement operator. Returns a reference to the changed address. + * + * @return Reference to the decremented underlying address. + */ + auto operator--() -> contiguous_pointer_iterator & + { + contiguous_pointer_iterator const old_value = *this; + ++ptr; + return old_value; + } + + /** + * @brief Pre increment operator. Returns a reference to the changed address. + * + * @return Reference to the incremented underlying address. + */ + auto operator++() -> contiguous_pointer_iterator & + { + ++ptr; + return *this; + } + + /** + * @brief Post decrement operator. Returns a copy of the address. + * + * @return Copy of the decremented underlying address. + */ + auto operator--(int) -> contiguous_pointer_iterator + { + auto const old_value = *this; + --ptr; + return old_value; + } + + /** + * @brief Post increment operator. Returns a copy of the address. + * + * @return Copy of the incremented underlying address. + */ + auto operator++(int) -> contiguous_pointer_iterator + { + auto const old_value = *this; + ++ptr; + return old_value; + } + + /** + * @brief Addition assignment operator. Returns a reference to the changed address. + * + * @param value Value we want to add to the underlying address. + * @return Reference to the changed underlying address. + */ + auto operator+=(difference_type value) -> contiguous_pointer_iterator & + { + ptr += value; + return *this; + } + + /** + * @brief Subtraction assignment operator. Returns a reference to the changed address. + * + * @param value Value we want to subtract from the underlying address. + * @return Reference to the changed underlying address. + */ + auto operator-=(difference_type value) -> contiguous_pointer_iterator & + { + ptr -= value; + return *this; + } + + /** + * @brief Addition operator. Returns the changed address. + * + * @param value Value we want to add to a copy of the underlying address. + * @return Copy of underlying address incremented by the given value. + */ + auto operator+(difference_type value) const -> contiguous_pointer_iterator + { + return contiguous_pointer_iterator{ptr + value}; + } + + /** + * @brief Subtraction operator. Returns the changed address. + * + * @param value Value we want to subtrcat from a copy of the underlying address. + * @return Copy of underlying address decremented by the given value. + */ + auto operator-(difference_type value) const -> contiguous_pointer_iterator + { + return contiguous_pointer_iterator{ptr - value}; + } + + /** + * @brief Subtraction operator. Returns the size difference between two iterators. + * + * @param other Other iterator we want to substract the underlying address with ours. + * @return Size difference between the underlying address of this instance and the given iterator. + */ + auto operator-(const contiguous_pointer_iterator & other) const -> difference_type { return ptr - other.ptr; } + + /** + * @brief Index operator overload. Returns a reference to the value at the given index. Simply returns the + * dereferenced underlying pointer incremented by the given index. + * + * @param index Index we want to access and get the value from. + * @return Reference to the value at the given index. + */ + auto operator[](difference_type index) const -> value_type & { return *(ptr + index); } + + /** + * @brief Defaulted comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether both iterators point to the same underlying address in memory. + */ + auto operator==(contiguous_pointer_iterator const & other) const -> bool = default; + + /** + * @brief Defaulted threeway comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether the given iterator is smaller or larger than this iterator. + */ + auto operator<=>(contiguous_pointer_iterator const & other) const -> std::strong_ordering = default; + + private: + pointer_type ptr = + {}; ///< Underlying value the iterator is currently pointing too and should increment or decrement. + }; + +} // namespace teachos::arch::stl + +#endif // TEACHOS_ARCH_X86_64_STL_CONTIGUOUS_POINTER_ITERATOR_HPP diff --git a/arch/x86_64/include/arch/stl/forward_value_iterator.hpp b/arch/x86_64/include/arch/stl/forward_value_iterator.hpp new file mode 100644 index 0000000..7c30964 --- /dev/null +++ b/arch/x86_64/include/arch/stl/forward_value_iterator.hpp @@ -0,0 +1,110 @@ +#ifndef TEACHOS_ARCH_X86_64_STL_FORWARD_VALUE_ITERATOR_HPP +#define TEACHOS_ARCH_X86_64_STL_FORWARD_VALUE_ITERATOR_HPP + +#include + +namespace teachos::arch::stl +{ + /** + * @brief Concept for a type to have a post and prefix increment operator, that returns the correct type. + */ + template + concept Incrementable = requires(T t) { + { ++t } -> std::same_as; + { t++ } -> std::same_as; + }; + + /** + * @brief Iterable concept for the forward value iterator, meaning the type itself is incrementable and comparable. + */ + template + concept Iterable = std::regular && Incrementable; + + /** + * @brief Generic forward iterator for given template type. Allows to easily use this iterator + * instance in algorithm calls. + * + * @note Allows any value that itself can be incremented until we have reached the end, does not interact with the + * address of the value in any way. + * + * @tparam T Value the iterator contains. + */ + template + struct forward_value_iterator + { + using iterator_category = std::forward_iterator_tag; ///< Iterator category of this type. + using difference_type = std::ptrdiff_t; ///< Type when diving one instance of this iterator by another. + using value_type = T; ///< Underlying value contained by this iterator. + using const_reference_type = + value_type const &; ///< Constant reference to value returned by dereference * operation. + using const_pointer_type = value_type const *; ///< Constant pointer to value returned by arrow -> operation. + + /** + * @brief Defaulted constructor. + */ + forward_value_iterator() = default; + + /** + * @brief Constructor. + * + * @param value Underlying value the iterator contains. + */ + explicit forward_value_iterator(value_type value) + : value(value) + { + // Nothing to do + } + + /** + * @brief Returns the initally given value. + * + * @return Reference to the value. + */ + auto operator*() const -> const_reference_type { return value; } + + /** + * @brief Gets pointer to the underlying value passed intially. + * + * @return Pointer to the underlying value passed intially. + */ + auto operator->() const -> const_pointer_type { return &value; } + + /** + * @brief Pre increment operator. Returns a reference to the changed value. + * + * @return Reference to the incremented underlying value. + */ + auto operator++() -> forward_value_iterator & + { + ++value; + return *this; + } + + /** + * @brief Post increment operator. Returns a copy of the value. + * + * @return Copy of the incremented underlying value. + */ + auto operator++(int) -> forward_value_iterator + { + auto const old_value = *this; + ++value; + return old_value; + } + + /** + * @brief Defaulted comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether both iterators point to the same underlying address in memory. + */ + auto operator==(forward_value_iterator const & other) const -> bool = default; + + private: + value_type value = + {}; ///< Underlying value the iterator is currently pointing too and should increment or decrement. + }; + +} // namespace teachos::arch::stl + +#endif // TEACHOS_ARCH_X86_64_STL_FORWARD_VALUE_ITERATOR_HPP diff --git a/arch/x86_64/include/arch/stl/mutex.hpp b/arch/x86_64/include/arch/stl/mutex.hpp new file mode 100644 index 0000000..d8fd9dc --- /dev/null +++ b/arch/x86_64/include/arch/stl/mutex.hpp @@ -0,0 +1,57 @@ +#ifndef TEACHOS_ARCH_X86_64_STL_MUTEX_HPP +#define TEACHOS_ARCH_X86_64_STL_MUTEX_HPP + +#include + +namespace teachos::arch::stl +{ + /** + * @brief Custom mutex implementation, that simply wraps an atomic boolean to keep track if the mutex is already in + * use by another thread or not. + */ + struct mutex + { + /** + * @brief Defaulted constructor. + */ + mutex() = default; + + /** + * @brief Defaulted destructor. + */ + ~mutex() = default; + + /** + * @brief Deleted copy constructor. + */ + mutex(const mutex &) = delete; + + /** + * @brief Deleted assignment operator. + */ + mutex & operator=(const mutex &) = delete; + + /** + * @brief Lock the mutex (blocks for as long as it is not available). + */ + auto lock() -> void; + + /** + * @brief Try to lock the mutex (non-blocking). + * + * @return True if lock has been acquired and false otherwise. + */ + auto try_lock() -> bool; + + /** + * @brief Unlock the mutex. + */ + auto unlock() -> void; + + private: + std::atomic locked = {false}; // Atomic boolean to track if mutex is locked or not. + }; + +} // namespace teachos::arch::stl + +#endif // TEACHOS_ARCH_X86_64_STL_MUTEX_HPP diff --git a/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp b/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp index 4e5459f..6b54451 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp @@ -2,14 +2,14 @@ namespace teachos::arch::context_switching::descriptor_table { - access_byte::access_byte(uint8_t flags, uint8_t type_field) + access_byte::access_byte(uint8_t flags) : _flags(flags) - , _type(type_field) { // Nothing to do. } - auto access_byte::contains_flags(std::bitset<4U> other) const -> bool { return (_flags & other) == other; } - - auto access_byte::get_type_field() const -> type_field { return _type; } + auto access_byte::contains_flags(std::bitset<8U> other) const -> bool + { + return (std::bitset<8U>{_flags} & other) == other; + } } // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp b/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp index 65f2e90..9e95182 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp @@ -1,14 +1,18 @@ #include "arch/context_switching/descriptor_table/gdt_flags.hpp" -#include "arch/exception_handling/assert.hpp" - namespace teachos::arch::context_switching::descriptor_table { - gdt_flags::gdt_flags(uint8_t flags) - : _flags(flags) + gdt_flags::gdt_flags(uint8_t flags, std::bitset<20U> limit) + : _limit_2(limit.to_ulong() >> 16U) + , _flags(flags) { // Nothing to do. } - auto gdt_flags::contains_flags(std::bitset<4U> other) const -> bool { return (_flags & other) == other; } + auto gdt_flags::contains_flags(std::bitset<4U> other) const -> bool + { + return (std::bitset<4U>{_flags} & other) == other; + } + + auto descriptor_table::gdt_flags::get_limit() const -> std::bitset<4U> { return std::bitset<4U>{_limit_2}; } } // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp b/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp index f4ea61b..c5554a7 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp @@ -1,6 +1,7 @@ #include "arch/context_switching/descriptor_table/global_descriptor_table.hpp" #include "arch/context_switching/descriptor_table/segment_descriptor.hpp" +#include "arch/exception_handling/assert.hpp" #include "arch/kernel/cpu/lgdt.hpp" #include "arch/stl/vector.hpp" @@ -10,33 +11,32 @@ namespace teachos::arch::context_switching::descriptor_table { segment_descriptor null_segment{0}; + std::bitset<20U> limit{0xFFFFF}; // Kernel space code segment access_byte kernel_code_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_KERNEL | - access_byte::CODE_OR_DATA_SEGMENT, - type_field::CODE_SEGMENT | type_field::READABLE}; - gdt_flags kernel_code_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::LENGTH}; - segment_descriptor kernel_code_segment{kernel_code_access_byte, kernel_code_gdt_flags, 0, 0xFFFFF}; + access_byte::CODE_OR_DATA_SEGMENT | access_byte::CODE_SEGMENT | + access_byte::READABLE}; + gdt_flags kernel_code_gdt_flags{gdt_flags::GRANU