diff options
| author | Matteo Gmür <matteo.gmuer1@ost.ch> | 2025-03-17 09:38:39 +0000 |
|---|---|---|
| committer | Matteo Gmür <matteo.gmuer1@ost.ch> | 2025-03-17 09:38:39 +0000 |
| commit | c56a8a74bc4e9662469db33a85c12586f202985a (patch) | |
| tree | 997056e9b2ef88af673856a2c2f017b3aa73723b /arch/x86_64 | |
| parent | 1658665ff3343382bc2af14ea87642aec544a606 (diff) | |
| download | teachos-c56a8a74bc4e9662469db33a85c12586f202985a.tar.xz teachos-c56a8a74bc4e9662469db33a85c12586f202985a.zip | |
Fix issue in vector
Diffstat (limited to 'arch/x86_64')
8 files changed, 92 insertions, 36 deletions
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 11f5dd4..de41762 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 @@ -70,10 +70,10 @@ namespace teachos::arch::context_switching::descriptor_table auto get_limit() const -> std::bitset<4U>; /** - * @brief Allows to compare the underlying std::bitset of two instances. + * @brief Allows to compare the underlying set bits 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. + * @return Whether the underlying set bits of both types are the same. */ auto operator==(gdt_flags const & other) const -> bool = default; diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table.hpp index ab8f1ac..75e1e9d 100644 --- a/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table.hpp +++ b/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table.hpp @@ -30,7 +30,7 @@ namespace teachos::arch::context_switching::descriptor_table * - User Code Segment * - User Data Segment * - * @return Created global_descriptor_table. + * @return Copy of the created global_descriptor_table. */ auto create_global_descriptor_table() -> global_descriptor_table; @@ -46,9 +46,9 @@ namespace teachos::arch::context_switching::descriptor_table * @brief Initializes the global_descriptor_table and task_state_segment by loading them * in the GDTR and TR registers respectively. * - * @return Created global_descriptor_table. + * @return Reference to the created global_descriptor_table. */ - auto initialize_global_descriptor_table() -> global_descriptor_table; + auto initialize_global_descriptor_table() -> global_descriptor_table &; } // 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 7454470..8714eb8 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 @@ -49,6 +49,14 @@ namespace teachos::arch::context_switching::descriptor_table */ auto get_segment_type() const -> segment_descriptor_type; + /** + * @brief Allows to compare the underlying bits of two instances. + * + * @param other Other instance that we want to compare with. + * @return Whether the underlying set bits of both types are the same. + */ + auto operator==(segment_descriptor const & other) const -> bool = default; + 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) diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/task_state_segment.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/task_state_segment.hpp index c3b0233..1e306af 100644 --- a/arch/x86_64/include/arch/context_switching/descriptor_table/task_state_segment.hpp +++ b/arch/x86_64/include/arch/context_switching/descriptor_table/task_state_segment.hpp @@ -24,9 +24,9 @@ namespace teachos::arch::context_switching::descriptor_table uint64_t ist6 = {}; uint64_t ist7 = {}; uint64_t : 64; - uint32_t : 32; + uint16_t : 16; uint16_t io_map_base_address = {}; }; } // namespace teachos::arch::context_switching::descriptor_table -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_TASK_STATE_SEGMENT_HPP
\ No newline at end of file +#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_TASK_STATE_SEGMENT_HPP diff --git a/arch/x86_64/include/arch/stl/vector.hpp b/arch/x86_64/include/arch/stl/vector.hpp index 112af57..f3d41fd 100644 --- a/arch/x86_64/include/arch/stl/vector.hpp +++ b/arch/x86_64/include/arch/stl/vector.hpp @@ -162,13 +162,13 @@ namespace teachos::arch::stl */ void push_back(T const & value) { - _data[_size] = value; - _size++; - if (_size == _capacity) { reserve(_capacity * 2); } + + _data[_size] = value; + _size++; } /** @@ -182,13 +182,13 @@ namespace teachos::arch::stl */ void push_back(T && value) { - _data[_size] = std::move(value); - _size++; - if (_size == _capacity) { reserve(_capacity * 2); } + + _data[_size] = std::move(value); + _size++; } /** @@ -206,13 +206,13 @@ namespace teachos::arch::stl template<class... Args> auto emplace_back(Args &&... args) -> T & { - _data[_size] = T{std::forward<Args>(args)...}; - auto const index = _size++; - if (_size == _capacity) { reserve(_capacity * 2); } + + _data[_size] = T{std::forward<Args>(args)...}; + auto const index = _size++; return _data[index]; } @@ -255,6 +255,30 @@ namespace teachos::arch::stl T const * cbegin() const noexcept { return begin(); } /** + * @brief Returns a reverse iterator to the first element of the reversed vector. It corresponds to the last element + * of the non-reversed vector. If the vector is empty, the returned iterator will be equal to rend(). + * + * @return Reverse iterator to the first element. + */ + T * rbegin() noexcept { return _data + _size - 1; } + + /** + * @brief Returns a reverse iterator to the first element of the reversed vector. It corresponds to the last element + * of the non-reversed vector. If the vector is empty, the returned iterator will be equal to rend(). + * + * @return Reverse iterator to the first element. + */ + T const * rbegin() const noexcept { return _data + _size - 1; } + + /** + * @brief Returns a reverse iterator to the first element of the reversed vector. It corresponds to the last element + * of the non-reversed vector. If the vector is empty, the returned iterator will be equal to rend(). + * + * @return Reverse iterator to the first element. + */ + T const * crbegin() const noexcept { return rbegin(); } + + /** * @brief Returns an iterator to the element following the last element of the vector. This element acts as a * placeholder, attempting to access it results in undefined behavior. * @@ -279,6 +303,33 @@ namespace teachos::arch::stl T const * cend() const noexcept { return end(); } /** + * @brief Returns a reverse iterator to the element following the last element of the reversed vector. It + * corresponds to the element preceding the first element of the non-reversed vector. This element acts as a + * placeholder, attempting to access it results in undefined behavior. + * + * @return Reverse iterator to the element following the last element. + */ + T * rend() noexcept { return _data + size - 1; } + + /** + * @brief Returns a reverse iterator to the element following the last element of the reversed vector. It + * corresponds to the element preceding the first element of the non-reversed vector. This element acts as a + * placeholder, attempting to access it results in undefined behavior. + * + * @return Reverse iterator to the element following the last element. + */ + T const * rend() const noexcept { return _data + size - 1; } + + /** + * @brief Returns a reverse iterator to the element following the last element of the reversed vector. It + * corresponds to the element preceding the first element of the non-reversed vector. This element acts as a + * placeholder, attempting to access it results in undefined behavior. + * + * @return Reverse iterator to the element following the last element. + */ + T const * crend() const noexcept { return rbegin(); } + + /** * @brief Returns a pointer to the underlying array serving as element storage. The pointer is such that range * [data(), data() + size()) is always a valid range, even if the container is empty (data() is not dereferenceable * in that case). @@ -320,7 +371,7 @@ namespace teachos::arch::stl * * @return Reference to the last element. */ - T & back() { return *end(); } + T & back() { return *rbegin(); } /** * @brief Returns a reference to the last element in the container. Calling back on an empty container causes @@ -328,7 +379,7 @@ namespace teachos::arch::stl * * @return Reference to the last element. */ - T const & back() const { return *end(); } + T const & back() const { return *rbegin(); } /** * @brief Increase the capacity of the vector (the total number of elements that the vector can hold without 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 77bd3e9..21a76e8 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 @@ -54,9 +54,12 @@ namespace teachos::arch::context_switching::descriptor_table create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_level::USER); segment_descriptor user_data_segment = create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_level::USER); + // Task State Segment needs to be kept alive + static auto tss = new task_state_segment(); + segment_descriptor tss_descriptor = create_task_state_segment_descriptor(tss); - global_descriptor_table global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment, - user_code_segment, user_data_segment}; + global_descriptor_table global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment, + user_code_segment, user_data_segment, tss_descriptor}; return global_descriptor_table; } @@ -67,20 +70,15 @@ namespace teachos::arch::context_switching::descriptor_table access_byte::TASK_STATE_SEGMENT_AVAILABLE}; gdt_flags tss_gdt_flags{0U, limit}; uint64_t tss_address = reinterpret_cast<uint64_t>(tss); - constexpr uint64_t tss_limit = sizeof(task_state_segment) - 1; - segment_descriptor tss_descriptor{tss_access_byte, tss_gdt_flags, tss_address, tss_limit}; - + constexpr uint64_t TSS_LIMIT = sizeof(task_state_segment) - 1; + segment_descriptor tss_descriptor{tss_access_byte, tss_gdt_flags, tss_address, TSS_LIMIT}; return tss_descriptor; } - auto initialize_global_descriptor_table() -> global_descriptor_table + auto initialize_global_descriptor_table() -> global_descriptor_table & { - auto gdt = create_global_descriptor_table(); - - // Add TSS segment descriptor to GDT - auto tss = new task_state_segment(); - auto tss_descriptor = create_task_state_segment_descriptor(tss); - gdt.push_back(tss_descriptor); + // Global Descriptor Table needs to be kept alive + static auto gdt = create_global_descriptor_table(); // Load GDT into GDTR global_descriptor_table_pointer gdt_pointer{static_cast<uint16_t>(gdt.size() - 1), &gdt}; @@ -91,14 +89,13 @@ namespace teachos::arch::context_switching::descriptor_table gdt_pointer == stored_gdt_pointer, "[Global Descriptor Table] Loaded GDTR value is not the same as the stored value."); - // Load Task Register (LTR) using the index of TSS descriptor - uint16_t tss_selector = (gdt.size() - 1) * sizeof(segment_descriptor); + // Calculate the offset of the gdt in bytes to the TSS descriptor + uint16_t const tss_selector = (gdt.size() - 1) * sizeof(segment_descriptor); kernel::cpu::load_task_register(tss_selector); auto stored_task_register = kernel::cpu::store_task_register(); arch::exception_handling::assert(tss_selector == stored_task_register, "[Global Descriptor Table] Loaded TR value is not the same as the stored value."); - return gdt; } } // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/src/kernel/cpu/tr.cpp b/arch/x86_64/src/kernel/cpu/tr.cpp index ad38d09..d0e037f 100644 --- a/arch/x86_64/src/kernel/cpu/tr.cpp +++ b/arch/x86_64/src/kernel/cpu/tr.cpp @@ -5,12 +5,12 @@ namespace teachos::arch::kernel::cpu auto store_task_register() -> uint16_t { uint16_t current_value{}; - asm("str %[output]" : [output] "=m"(current_value)); + asm("str %[output]" : [output] "=r"(current_value)); return current_value; } auto load_task_register(uint16_t gdt_offset) -> void { - asm volatile("ltr %[input]" : /* no output from call */ : [input] "m"(gdt_offset)); + asm volatile("ltr %[input]" : /* no output from call */ : [input] "r"(gdt_offset)); } } // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index c1e134a..da6d6d3 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -60,7 +60,7 @@ namespace teachos::arch::kernel heap_test(); - auto global_descriptor_table = context_switching::descriptor_table::initialize_global_descriptor_table(); + decltype(auto) global_descriptor_table = context_switching::descriptor_table::initialize_global_descriptor_table(); (void)global_descriptor_table.at(1); video::vga::text::write("GDT FILLED", video::vga::text::common_attributes::green_on_black); } |
