From 8d14c729c43ee555c240a043e3909617e4fa5043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Thu, 27 Feb 2025 09:24:17 +0000 Subject: Add files to cmake and implement gdt flags --- arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp (limited to 'arch/x86_64/src') 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 new file mode 100644 index 0000000..8a05956 --- /dev/null +++ b/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp @@ -0,0 +1,6 @@ +#include "arch/context_switching/descriptor_table/gdt_flags.hpp" + +namespace teachos::arch::context_switching::descriptor_table +{ + auto gdt_flags::contains_flags(std::bitset<4U> other) const -> bool { return (flags & other) == other; } +} // namespace teachos::arch::context_switching::descriptor_table -- cgit v1.2.3 From d8a8efe3e8d90ec83069d1c934ff319626e87a2d Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 27 Feb 2025 10:13:35 +0000 Subject: add descriptor_table access_byte --- arch/x86_64/src/boot/boot.s | 4 ++-- .../src/context_switching/descriptor_table/access_byte.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp (limited to 'arch/x86_64/src') diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s index 2197dce..dbea42a 100644 --- a/arch/x86_64/src/boot/boot.s +++ b/arch/x86_64/src/boot/boot.s @@ -197,10 +197,10 @@ _start: call enable_paging call enable_sse - cli // Clears the interrupt flag during the GDT setup + cli /* Clears the interrupt flag during the GDT setup */ lgdt (global_descriptor_table_pointer) jmp $global_descriptor_table_code,$_transition_to_long_mode - // The interrupt flag is set in cpp after setting up the GDT + /* The interrupt flag is set in cpp after setting up the GDT */ call halt 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 new file mode 100644 index 0000000..15a0947 --- /dev/null +++ b/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp @@ -0,0 +1,14 @@ +#include "arch/context_switching/descriptor_table/access_byte.hpp" + +#include + +namespace teachos::arch::context_switching::descriptor_table +{ + auto access_byte::contains_flags(std::bitset<8U> other) const -> bool { return (flags & other) == other; } + + auto access_byte::get_privilege_level() const -> privilege_level + { + constexpr uint8_t PRIVILEGE_MASK = 0b0110'0000; + return static_cast(flags.to_ulong() & PRIVILEGE_MASK); + } +} // namespace teachos::arch::context_switching::descriptor_table -- cgit v1.2.3 From 051307f49f4cdfb86c527a475ab21feea4a664d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Tue, 4 Mar 2025 18:01:49 +0000 Subject: Add more methods to vector to mimic stl interface partially. --- arch/x86_64/src/memory/main.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/x86_64/src') diff --git a/arch/x86_64/src/memory/main.cpp b/arch/x86_64/src/memory/main.cpp index a6f91d9..08308db 100644 --- a/arch/x86_64/src/memory/main.cpp +++ b/arch/x86_64/src/memory/main.cpp @@ -7,6 +7,9 @@ #include "arch/memory/heap/heap_allocator.hpp" #include "arch/memory/paging/active_page_table.hpp" #include "arch/memory/paging/kernel_mapper.hpp" +#include "arch/stl/shared_pointer.hpp" +#include "arch/stl/unique_pointer.hpp" +#include "arch/stl/vector.hpp" namespace teachos::arch::memory { @@ -49,5 +52,11 @@ namespace teachos::arch::memory remap_heap(allocator, active_table); video::vga::text::write("Heap remapping successful", video::vga::text::common_attributes::green_on_black); video::vga::text::newline(); + + auto test2 = stl::make_unique(0); + auto test3 = stl::make_shared(0); + if (test2 && test3) + { + } } } // namespace teachos::arch::memory -- cgit v1.2.3 From 06d5e5872838bd1528493b62b4dc28d44b54aa47 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Sun, 9 Mar 2025 09:30:01 +0000 Subject: add doxygen comments to shared and unique pointer --- arch/x86_64/src/memory/main.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'arch/x86_64/src') diff --git a/arch/x86_64/src/memory/main.cpp b/arch/x86_64/src/memory/main.cpp index 08308db..15e89c0 100644 --- a/arch/x86_64/src/memory/main.cpp +++ b/arch/x86_64/src/memory/main.cpp @@ -52,11 +52,5 @@ namespace teachos::arch::memory remap_heap(allocator, active_table); video::vga::text::write("Heap remapping successful", video::vga::text::common_attributes::green_on_black); video::vga::text::newline(); - - auto test2 = stl::make_unique(0); - auto test3 = stl::make_shared(0); - if (test2 && test3) - { - } } -} // namespace teachos::arch::memory +} // namespace teachos::arch::memory \ No newline at end of file -- cgit v1.2.3 From 1a6d41362447531a2ea5ee344c15b9aaa6c2090a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Sun, 9 Mar 2025 16:52:17 +0000 Subject: Adjust comments and implement remaining interface for STL classes. --- arch/x86_64/src/memory/main.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch/x86_64/src') diff --git a/arch/x86_64/src/memory/main.cpp b/arch/x86_64/src/memory/main.cpp index 15e89c0..a6f91d9 100644 --- a/arch/x86_64/src/memory/main.cpp +++ b/arch/x86_64/src/memory/main.cpp @@ -7,9 +7,6 @@ #include "arch/memory/heap/heap_allocator.hpp" #include "arch/memory/paging/active_page_table.hpp" #include "arch/memory/paging/kernel_mapper.hpp" -#include "arch/stl/shared_pointer.hpp" -#include "arch/stl/unique_pointer.hpp" -#include "arch/stl/vector.hpp" namespace teachos::arch::memory { @@ -53,4 +50,4 @@ namespace teachos::arch::memory video::vga::text::write("Heap remapping successful", video::vga::text::common_attributes::green_on_black); video::vga::text::newline(); } -} // namespace teachos::arch::memory \ No newline at end of file +} // namespace teachos::arch::memory -- cgit v1.2.3 From c5151739698620e77622423c109e638f903f01c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 10 Mar 2025 13:42:38 +0000 Subject: Adjust register segment descriptors to possible states --- .../descriptor_table/access_byte.cpp | 15 +++++++------- .../descriptor_table/gdt_flags.cpp | 24 +++++++++++++++++++++- .../descriptor_table/type_field.cpp | 12 +++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 arch/x86_64/src/context_switching/descriptor_table/type_field.cpp (limited to 'arch/x86_64/src') 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 15a0947..7a2b0b0 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 @@ -1,14 +1,15 @@ #include "arch/context_switching/descriptor_table/access_byte.hpp" -#include - namespace teachos::arch::context_switching::descriptor_table { - auto access_byte::contains_flags(std::bitset<8U> other) const -> bool { return (flags & other) == other; } - - auto access_byte::get_privilege_level() const -> privilege_level + access_byte::access_byte(uint8_t flags) + : _flags(flags) + , _type(flags) { - constexpr uint8_t PRIVILEGE_MASK = 0b0110'0000; - return static_cast(flags.to_ulong() & PRIVILEGE_MASK); + // 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; } } // 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 8a05956..8e1e939 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,6 +1,28 @@ #include "arch/context_switching/descriptor_table/gdt_flags.hpp" +#include "arch/exception_handling/assert.hpp" + namespace teachos::arch::context_switching::descriptor_table { - auto gdt_flags::contains_flags(std::bitset<4U> other) const -> bool { return (flags & other) == other; } + gdt_flags::gdt_flags(uint8_t flags, segment_descriptor_type type) + : _flags(flags << 5U) + { + switch (type) + { + case segment_descriptor_type::SYSTEM_SEGMENT: + _flags.set(2, false); + _flags.set(3, false); + break; + case segment_descriptor_type::DATA_SEGMENT: + _flags.set(3, false); + break; + case segment_descriptor_type::CODE_SEGMENT: + exception_handling::assert((contains_flags(LENGTH) && !contains_flags(DEFAULT_LENGTH)) || + !contains_flags(LENGTH), + "[GDT] Flags of code segment descriptor has both "); + break; + } + } + + auto gdt_flags::contains_flags(std::bitset<4U> other) const -> bool { return (_flags & other) == other; } } // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/src/context_switching/descriptor_table/type_field.cpp b/arch/x86_64/src/context_switching/descriptor_table/type_field.cpp new file mode 100644 index 0000000..d967a97 --- /dev/null +++ b/arch/x86_64/src/context_switching/descriptor_table/type_field.cpp @@ -0,0 +1,12 @@ +#include "arch/context_switching/descriptor_table/type_field.hpp" + +namespace teachos::arch::context_switching::descriptor_table +{ + type_field::type_field(uint8_t flags) + : _flags(flags) + { + // Nothing to do. + } + + auto type_field::contains_flags(std::bitset<4U> other) const -> bool { return (_flags & other) == other; } +} // namespace teachos::arch::context_switching::descriptor_table -- cgit v1.2.3 From 52fffdf2c76def4a875e0328eb45d74c6e97e805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 10 Mar 2025 16:05:31 +0000 Subject: Adjust segment descriptor to use defined helpers --- .../descriptor_table/segment_descriptor.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp (limited to 'arch/x86_64/src') diff --git a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp new file mode 100644 index 0000000..fb9c034 --- /dev/null +++ b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp @@ -0,0 +1,13 @@ +#include "arch/context_switching/descriptor_table/segment_descriptor.hpp" + +namespace teachos::arch::context_switching::descriptor_table +{ + segment_descriptor::segment_descriptor(uint128_t flags) + : _reserved(flags) + , _access(flags) + , _flag(flags, segment_descriptor_type::SYSTEM_SEGMENT) + , _base(flags) + , _limit(flags) + { + } +} // namespace teachos::arch::context_switching::descriptor_table -- cgit v1.2.3 From 569cf73d1fa14ec11afbb37464d2c356d55d64b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 10 Mar 2025 16:35:01 +0000 Subject: Implement segment descriptor --- .../descriptor_table/gdt_flags.cpp | 18 ++---------------- .../descriptor_table/segment_descriptor.cpp | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 21 deletions(-) (limited to 'arch/x86_64/src') 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 8e1e939..8fbf869 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 @@ -4,24 +4,10 @@ namespace teachos::arch::context_switching::descriptor_table { - gdt_flags::gdt_flags(uint8_t flags, segment_descriptor_type type) + gdt_flags::gdt_flags(uint8_t flags) : _flags(flags << 5U) { - switch (type) - { - case segment_descriptor_type::SYSTEM_SEGMENT: - _flags.set(2, false); - _flags.set(3, false); - break; - case segment_descriptor_type::DATA_SEGMENT: - _flags.set(3, false); - break; - case segment_descriptor_type::CODE_SEGMENT: - exception_handling::assert((contains_flags(LENGTH) && !contains_flags(DEFAULT_LENGTH)) || - !contains_flags(LENGTH), - "[GDT] Flags of code segment descriptor has both "); - break; - } + // Nothing to do. } auto gdt_flags::contains_flags(std::bitset<4U> other) const -> bool { return (_flags & other) == other; } diff --git a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp index fb9c034..57564f2 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp @@ -3,11 +3,22 @@ namespace teachos::arch::context_switching::descriptor_table { segment_descriptor::segment_descriptor(uint128_t flags) - : _reserved(flags) - , _access(flags) - , _flag(flags, segment_descriptor_type::SYSTEM_SEGMENT) - , _base(flags) - , _limit(flags) + : _reserved(flags >> 96U) + , _access((flags >> 40U) << 80U) + , _flag((flags >> 52U) << 72U) + , _base(((flags >> 64U) << 32U) << 32U | ((flags >> 56U) << 64U) << 24U | (flags >> 16U) << 88U) + , _limit(((flags >> 48U) << 72U) << 16U | flags << 112U) { + // Nothing to do. + } + + auto segment_descriptor::get_segment_type() const -> segment_descriptor_type + { + if (!_access.contains_flags(access_byte::CODE_OR_DATA_SEGMENT)) + { + return segment_descriptor_type::SYSTEM_SEGMENT; + } + return _access.get_type_field().contains_flags(type_field::CODE_SEGMENT) ? segment_descriptor_type::CODE_SEGMENT + : segment_descriptor_type::DATA_SEGMENT; } } // namespace teachos::arch::context_switching::descriptor_table -- cgit v1.2.3 From b8a0024ee71a64ec0e87a1e2d0c0c7280dc954e6 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 13 Mar 2025 09:36:00 +0000 Subject: create GDT and fix segment descriptor bit order --- .../descriptor_table/access_byte.cpp | 4 +- .../descriptor_table/gdt_flags.cpp | 2 +- .../descriptor_table/segment_descriptor.cpp | 22 ++++++++-- arch/x86_64/src/kernel/main.cpp | 50 ++++++++++++++++++++++ 4 files changed, 72 insertions(+), 6 deletions(-) (limited to 'arch/x86_64/src') 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 7a2b0b0..4e5459f 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,9 +2,9 @@ namespace teachos::arch::context_switching::descriptor_table { - access_byte::access_byte(uint8_t flags) + access_byte::access_byte(uint8_t flags, uint8_t type_field) : _flags(flags) - , _type(flags) + , _type(type_field) { // Nothing to do. } 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 8fbf869..65f2e90 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 @@ -5,7 +5,7 @@ namespace teachos::arch::context_switching::descriptor_table { gdt_flags::gdt_flags(uint8_t flags) - : _flags(flags << 5U) + : _flags(flags) { // Nothing to do. } diff --git a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp index 57564f2..ab8eaba 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp @@ -4,7 +4,7 @@ namespace teachos::arch::context_switching::descriptor_table { segment_descriptor::segment_descriptor(uint128_t flags) : _reserved(flags >> 96U) - , _access((flags >> 40U) << 80U) + , _access((flags >> 44U) << 80U, (flags >> 40U) << 84U) , _flag((flags >> 52U) << 72U) , _base(((flags >> 64U) << 32U) << 32U | ((flags >> 56U) << 64U) << 24U | (flags >> 16U) << 88U) , _limit(((flags >> 48U) << 72U) << 16U | flags << 112U) @@ -12,13 +12,29 @@ namespace teachos::arch::context_switching::descriptor_table // Nothing to do. } + segment_descriptor::segment_descriptor(access_byte access_byte, gdt_flags flags, uint64_t base, + std::bitset<20U> limit) + : _reserved(0U) + , _access(access_byte) + , _flag(flags) + , _base(base) + , _limit(limit) + { + // Nothing to do + } + auto segment_descriptor::get_segment_type() const -> segment_descriptor_type { if (!_access.contains_flags(access_byte::CODE_OR_DATA_SEGMENT)) { return segment_descriptor_type::SYSTEM_SEGMENT; } - return _access.get_type_field().contains_flags(type_field::CODE_SEGMENT) ? segment_descriptor_type::CODE_SEGMENT - : segment_descriptor_type::DATA_SEGMENT; + + if (_access.get_type_field().contains_flags(type_field::CODE_SEGMENT)) + { + return segment_descriptor_type::CODE_SEGMENT; + } + + return segment_descriptor_type::DATA_SEGMENT; } } // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 472aed5..d3938ed 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,9 +1,11 @@ #include "arch/kernel/main.hpp" +#include "arch/context_switching/descriptor_table/segment_descriptor.hpp" #include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/main.hpp" #include "arch/memory/multiboot/reader.hpp" +#include "arch/stl/vector.hpp" #include "arch/video/vga/text.hpp" namespace teachos::arch::kernel @@ -57,5 +59,53 @@ namespace teachos::arch::kernel memory::heap::global_heap_allocator::register_heap_allocator(memory::heap::heap_allocator_type::LINKED_LIST); heap_test(); + + using context_switching::descriptor_table::access_byte; + using context_switching::descriptor_table::gdt_flags; + using context_switching::descriptor_table::segment_descriptor; + using context_switching::descriptor_table::segment_descriptor_type; + using context_switching::descriptor_table::type_field; + + segment_descriptor null_segment{0}; + + // 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}; + + // Kernel space data segment + access_byte kernel_data_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_KERNEL | + access_byte::CODE_OR_DATA_SEGMENT, + type_field::WRITABLE}; + gdt_flags kernel_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND}; + segment_descriptor kernel_data_segment{kernel_data_access_byte, kernel_data_gdt_flags, 0, 0xFFFFF}; + + // User space code segment + access_byte user_code_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_USER | + access_byte::CODE_OR_DATA_SEGMENT, + type_field::CODE_SEGMENT | type_field::READABLE}; + gdt_flags user_code_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::LENGTH}; + segment_descriptor user_code_segment{user_code_access_byte, user_code_gdt_flags, 0, 0xFFFFF}; + + // User space data segment + access_byte user_data_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_USER | + access_byte::CODE_OR_DATA_SEGMENT, + type_field::WRITABLE}; + gdt_flags user_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND}; + segment_descriptor user_data_segment{user_data_access_byte, user_data_gdt_flags, 0, 0xFFFFF}; + + stl::vector global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment, + user_code_segment, user_data_segment}; + + decltype(auto) x = global_descriptor_table.at(1); + if (global_descriptor_table.size() == 0) + { + } + if (x.get_segment_type() == segment_descriptor_type::CODE_SEGMENT) + { + } + video::vga::text::write("GDT FILLED", video::vga::text::common_attributes::green_on_black); } } // namespace teachos::arch::kernel -- cgit v1.2.3 From 34c36096e55ac678e29c58f7336b419647e805b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Thu, 13 Mar 2025 10:00:42 +0000 Subject: Fix segment descriptor bit order of private members --- .../descriptor_table/segment_descriptor.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'arch/x86_64/src') diff --git a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp index ab8eaba..a743ad2 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp @@ -3,22 +3,26 @@ namespace teachos::arch::context_switching::descriptor_table { segment_descriptor::segment_descriptor(uint128_t flags) - : _reserved(flags >> 96U) + : _limit_1(flags << 112U) + , _base_1((flags >> 16U) << 88U) , _access((flags >> 44U) << 80U, (flags >> 40U) << 84U) + , _limit_2((flags >> 48U) << 72U) , _flag((flags >> 52U) << 72U) - , _base(((flags >> 64U) << 32U) << 32U | ((flags >> 56U) << 64U) << 24U | (flags >> 16U) << 88U) - , _limit(((flags >> 48U) << 72U) << 16U | flags << 112U) + , _base_2((flags >> 56U) << 32U) + , _reserved(flags >> 96U) { // Nothing to do. } segment_descriptor::segment_descriptor(access_byte access_byte, gdt_flags flags, uint64_t base, std::bitset<20U> limit) - : _reserved(0U) + : _limit_1((limit.to_ulong() << 4U) >> 16U) + , _base_1((base << 40U) >> 40U) , _access(access_byte) + , _limit_2(limit.to_ulong() >> 16U) , _flag(flags) - , _base(base) - , _limit(limit) + , _base_2(base >> 24U) + , _reserved(0U) { // Nothing to do } -- cgit v1.2.3 From 2e4cbd473ff3bb7ac7371af39becf830b4fb753b Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 13 Mar 2025 14:05:45 +0000 Subject: IN_PROGRESS implement gdt initialization --- arch/x86_64/src/boot/boot.s | 2 +- .../descriptor_table/global_descriptor_table.cpp | 57 +++++++++++++++++ arch/x86_64/src/kernel/cpu/control_register.cpp | 72 ++++++++++++++++++++++ arch/x86_64/src/kernel/cpu/msr.cpp | 31 ++++++++++ arch/x86_64/src/kernel/cpu/ss.cpp | 33 ++++++++++ arch/x86_64/src/kernel/cpu/tlb.cpp | 16 +++++ arch/x86_64/src/kernel/main.cpp | 44 ++----------- arch/x86_64/src/memory/cpu/control_register.cpp | 72 ---------------------- arch/x86_64/src/memory/cpu/msr.cpp | 31 ---------- arch/x86_64/src/memory/cpu/tlb.cpp | 16 ----- arch/x86_64/src/memory/main.cpp | 4 +- 11 files changed, 216 insertions(+), 162 deletions(-) create mode 100644 arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp create mode 100644 arch/x86_64/src/kernel/cpu/control_register.cpp create mode 100644 arch/x86_64/src/kernel/cpu/msr.cpp create mode 100644 arch/x86_64/src/kernel/cpu/ss.cpp create mode 100644 arch/x86_64/src/kernel/cpu/tlb.cpp delete mode 100644 arch/x86_64/src/memory/cpu/control_register.cpp delete mode 100644 arch/x86_64/src/memory/cpu/msr.cpp delete mode 100644 arch/x86_64/src/memory/cpu/tlb.cpp (limited to 'arch/x86_64/src') diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s index dbea42a..39bfe33 100644 --- a/arch/x86_64/src/boot/boot.s +++ b/arch/x86_64/src/boot/boot.s @@ -199,7 +199,7 @@ _start: cli /* Clears the interrupt flag during the GDT setup */ lgdt (global_descriptor_table_pointer) - jmp $global_descriptor_table_code,$_transition_to_long_mode + jmp $global_descriptor_table_code, $_transition_to_long_mode /* The interrupt flag is set in cpp after setting up the GDT */ call halt 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 new file mode 100644 index 0000000..1cba13c --- /dev/null +++ b/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp @@ -0,0 +1,57 @@ +#include "global_descriptor_table.hpp" + +#include "arch/stl/vector.hpp" + +#include "segment_descriptor.hpp" + +namespace teachos::arch::context_switching::descriptor_table +{ + auto create_global_descriptor_table() -> global_descriptor_table + { + segment_descriptor null_segment{0}; + + // 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}; + + // Kernel space data segment + access_byte kernel_data_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_KERNEL | + access_byte::CODE_OR_DATA_SEGMENT, + type_field::WRITABLE}; + gdt_flags kernel_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND}; + segment_descriptor kernel_data_segment{kernel_data_access_byte, kernel_data_gdt_flags, 0, 0xFFFFF}; + + // User space code segment + access_byte user_code_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_USER | + access_byte::CODE_OR_DATA_SEGMENT, + type_field::CODE_SEGMENT | type_field::READABLE}; + gdt_flags user_code_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::LENGTH}; + segment_descriptor user_code_segment{user_code_access_byte, user_code_gdt_flags, 0, 0xFFFFF}; + + // User space data segment + access_byte user_data_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_USER | + access_byte::CODE_OR_DATA_SEGMENT, + type_field::WRITABLE}; + gdt_flags user_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND}; + segment_descriptor user_data_segment{user_data_access_byte, user_data_gdt_flags, 0, 0xFFFFF}; + + stl::vector global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment, + user_code_segment, user_data_segment}; + return global_descriptor_table; + } + + auto load_global_descriptor_table(global_descriptor_table_pointer gdt_pointer) -> void + { + // + } + + auto initialize_global_descriptor_table() -> global_descriptor_table + { + global_descriptor_table gdt{create_global_descriptor_table()}; + global_descriptor_table_pointer gdt_pointer{gdt.size() - 1, &gdt}; + load_global_descriptor_table(gdt_pointer); + } +} // namespace teachos::arch::context_switching::descriptor_table \ No newline at end of file diff --git a/arch/x86_64/src/kernel/cpu/control_register.cpp b/arch/x86_64/src/kernel/cpu/control_register.cpp new file mode 100644 index 0000000..3051bae --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/control_register.cpp @@ -0,0 +1,72 @@ +#include "arch/kernel/cpu/control_register.hpp" + +#include "arch/exception_handling/panic.hpp" + +#include + +namespace teachos::arch::memory::cpu +{ + auto read_control_register(control_register cr) -> uint64_t + { + uint64_t current_value; + switch (cr) + { + case control_register::CR0: + asm volatile("mov %%cr0, %[output]" : [output] "=r"(current_value)); + break; + case control_register::CR2: + asm volatile("mov %%cr2, %[output]" : [output] "=r"(current_value)); + break; + case control_register::CR3: + asm volatile("mov %%cr3, %[output]" : [output] "=r"(current_value)); + break; + case control_register::CR4: + asm volatile("mov %%cr4, %[output]" : [output] "=r"(current_value)); + break; + default: + exception_handling::panic("[Control Register] Attempted to read non-existent or reserved control register"); + break; + } + return current_value; + } + + auto write_control_register(control_register cr, uint64_t new_value) -> void + { + switch (cr) + { + case control_register::CR0: + asm volatile("mov %[input], %%cr0" + : /* no output from call */ + : [input] "r"(new_value) + : "memory"); + break; + case control_register::CR2: + asm volatile("mov %[input], %%cr2" + : /* no output from call */ + : [input] "r"(new_value) + : "memory"); + break; + case control_register::CR3: + asm volatile("mov %[input], %%cr3" + : /* no output from call */ + : [input] "r"(new_value) + : "memory"); + break; + case control_register::CR4: + asm volatile("mov %[input], %%cr4" + : /* no output from call */ + : [input] "r"(new_value) + : "memory"); + break; + default: + exception_handling::panic("[Control Register] Attempted to write non-existent or reserved control register"); + break; + } + } + + auto set_cr0_bit(cr0_flags flag) -> void + { + auto const cr0 = read_control_register(control_register::CR0); + write_control_register(control_register::CR0, static_cast::type>(flag) | cr0); + } +} // namespace teachos::arch::memory::cpu diff --git a/arch/x86_64/src/kernel/cpu/msr.cpp b/arch/x86_64/src/kernel/cpu/msr.cpp new file mode 100644 index 0000000..082bca9 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/msr.cpp @@ -0,0 +1,31 @@ +#include "arch/kernel/cpu/msr.hpp" + +namespace teachos::arch::memory::cpu +{ + namespace + { + auto constexpr IA32_EFER_ADDRESS = 0xC0000080; + } + + auto read_msr(uint32_t msr) -> uint64_t + { + uint32_t low, high; + asm volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); + return (static_cast(high) << 32) | low; + } + + auto write_msr(uint32_t msr, uint64_t value) -> void + { + uint32_t low = value & 0xFFFFFFFF; + uint32_t high = value >> 32; + asm volatile("wrmsr" + : /* no output from call */ + : "c"(msr), "a"(low), "d"(high)); + } + + auto set_efer_bit(efer_flags flag) -> void + { + auto const efer = read_msr(IA32_EFER_ADDRESS); + write_msr(IA32_EFER_ADDRESS, static_cast::type>(flag) | efer); + } +} // namespace teachos::arch::memory::cpu diff --git a/arch/x86_64/src/kernel/cpu/ss.cpp b/arch/x86_64/src/kernel/cpu/ss.cpp new file mode 100644 index 0000000..b7e52e1 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/ss.cpp @@ -0,0 +1,33 @@ +#include "arch/kernel/cpu/ss.hpp" + +namespace teachos::arch::memory::cpu +{ + segment_selector::segment_selector(uint16_t index, std::bitset<1U> table_indicator, + std::bitset<2U> requested_privilege_level) + : index(index) + , table_indicator(table_indicator) + , requested_privilege_level(requested_privilege_level) + { + // Nothing to do + } + + auto segment_selector::to_uint16() const -> uint16_t + { + return static_cast((index << 3) | (table_indicator.to_ulong() << 2) | + requested_privilege_level.to_ulong()); + } + + auto read_ss() -> uint16_t + { + uint16_t ss; + __asm__("mov %%ss, %0" : "=r"(ss)); + return ss; + } + + auto write_ss(segment_selector selector) -> void + { + uint16_t ss = selector.to_uint16(); + __asm__("mov %0, %%ss" ::"r"(ss)); + } + +} // namespace teachos::arch::memory::cpu \ No newline at end of file diff --git a/arch/x86_64/src/kernel/cpu/tlb.cpp b/arch/x86_64/src/kernel/cpu/tlb.cpp new file mode 100644 index 0000000..e753c2c --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/tlb.cpp @@ -0,0 +1,16 @@ +#include "arch/kernel/cpu/tlb.hpp" + +#include "arch/kernel/cpu/control_register.hpp" + +namespace teachos::arch::memory::cpu +{ + auto tlb_flush(paging::virtual_address address) -> void + { + asm volatile("invlpg (%[input])" : /* no output from call */ : [input] "r"(address) : "memory"); + } + + auto tlb_flush_all() -> void + { + write_control_register(cpu::control_register::CR3, read_control_register(cpu::control_register::CR3)); + } +} // namespace teachos::arch::memory::cpu diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index d3938ed..4db9599 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,6 +1,6 @@ #include "arch/kernel/main.hpp" -#include "arch/context_switching/descriptor_table/segment_descriptor.hpp" +#include "arch/context_switching/descriptor_table/global_descriptor_table.hpp" #include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/main.hpp" @@ -60,50 +60,14 @@ namespace teachos::arch::kernel heap_test(); - using context_switching::descriptor_table::access_byte; - using context_switching::descriptor_table::gdt_flags; - using context_switching::descriptor_table::segment_descriptor; - using context_switching::descriptor_table::segment_descriptor_type; - using context_switching::descriptor_table::type_field; - - segment_descriptor null_segment{0}; - - // 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}; - - // Kernel space data segment - access_byte kernel_data_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_KERNEL | - access_byte::CODE_OR_DATA_SEGMENT, - type_field::WRITABLE}; - gdt_flags kernel_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND}; - segment_descriptor kernel_data_segment{kernel_data_access_byte, kernel_data_gdt_flags, 0, 0xFFFFF}; - - // User space code segment - access_byte user_code_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_USER | - access_byte::CODE_OR_DATA_SEGMENT, - type_field::CODE_SEGMENT | type_field::READABLE}; - gdt_flags user_code_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::LENGTH}; - segment_descriptor user_code_segment{user_code_access_byte, user_code_gdt_flags, 0, 0xFFFFF}; - - // User space data segment - access_byte user_data_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_USER | - access_byte::CODE_OR_DATA_SEGMENT, - type_field::WRITABLE}; - gdt_flags user_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND}; - segment_descriptor user_data_segment{user_data_access_byte, user_data_gdt_flags, 0, 0xFFFFF}; - - stl::vector global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment, - user_code_segment, user_data_segment}; + context_switching::descriptor_table::global_descriptor_table global_descriptor_table{ + context_switching::descriptor_table::initialize_global_descriptor_table()}; decltype(auto) x = global_descriptor_table.at(1); if (global_descriptor_table.size() == 0) { } - if (x.get_segment_type() == segment_descriptor_type::CODE_SEGMENT) + if (x.get_segment_type() == context_switching::descriptor_table::segment_descriptor_type::CODE_SEGMENT) { } video::vga::text::write("GDT FILLED", video::vga::text::common_attributes::green_on_black); diff --git a/arch/x86_64/src/memory/cpu/control_register.cpp b/arch/x86_64/src/memory/cpu/control_register.cpp deleted file mode 100644 index 7ee88b5..0000000 --- a/arch/x86_64/src/memory/cpu/control_register.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "arch/memory/cpu/control_register.hpp" - -#include "arch/exception_handling/panic.hpp" - -#include - -namespace teachos::arch::memory::cpu -{ - auto read_control_register(control_register cr) -> uint64_t - { - uint64_t current_value; - switch (cr) - { - case control_register::CR0: - asm volatile("mov %%cr0, %[output]" : [output] "=r"(current_value)); - break; - case control_register::CR2: - asm volatile("mov %%cr2, %[output]" : [output] "=r"(current_value)); - break; - case control_register::CR3: - asm volatile("mov %%cr3, %[output]" : [output] "=r"(current_value)); - break; - case control_register::CR4: - asm volatile("mov %%cr4, %[output]" : [output] "=r"(current_value)); - break; - default: - exception_handling::panic("[Control Register] Attempted to read non-existent or reserved control register"); - break; - } - return current_value; - } - - auto write_control_register(control_register cr, uint64_t new_value) -> void - { - switch (cr) - { - case control_register::CR0: - asm volatile("mov %[input], %%cr0" - : /* no output from call */ - : [input] "r"(new_value) - : "memory"); - break; - case control_register::CR2: - asm volatile("mov %[input], %%cr2" - : /* no output from call */ - : [input] "r"(new_value) - : "memory"); - break; - case control_register::CR3: - asm volatile("mov %[input], %%cr3" - : /* no output from call */ - : [input] "r"(new_value) - : "memory"); - break; - case control_register::CR4: - asm volatile("mov %[input], %%cr4" - : /* no output from call */ - : [input] "r"(new_value) - : "memory"); - break; - default: - exception_handling::panic("[Control Register] Attempted to write non-existent or reserved control register"); - break; - } - } - - auto set_cr0_bit(cr0_flags flag) -> void - { - auto const cr0 = read_control_register(control_register::CR0); - write_control_register(control_register::CR0, static_cast::type>(flag) | cr0); - } -} // namespace teachos::arch::memory::cpu diff --git a/arch/x86_64/src/memory/cpu/msr.cpp b/arch/x86_64/src/memory/cpu/msr.cpp deleted file mode 100644 index b83f902..0000000 --- a/arch/x86_64/src/memory/cpu/msr.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "arch/memory/cpu/msr.hpp" - -namespace teachos::arch::memory::cpu -{ - namespace - { - auto constexpr IA32_EFER_ADDRESS = 0xC0000080; - } - - auto read_msr(uint32_t msr) -> uint64_t - { - uint32_t low, high; - asm volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); - return (static_cast(high) << 32) | low; - } - - auto write_msr(uint32_t msr, uint64_t value) -> void - { - uint32_t low = value & 0xFFFFFFFF; - uint32_t high = value >> 32; - asm volatile("wrmsr" - : /* no output from call */ - : "c"(msr), "a"(low), "d"(high)); - } - - auto set_efer_bit(efer_flags flag) -> void - { - auto const efer = read_msr(IA32_EFER_ADDRESS); - write_msr(IA32_EFER_ADDRESS, static_cast::type>(flag) | efer); - } -} // namespace teachos::arch::memory::cpu diff --git a/arch/x86_64/src/memory/cpu/tlb.cpp b/arch/x86_64/src/memory/cpu/tlb.cpp deleted file mode 100644 index 591d9fc..0000000 --- a/arch/x86_64/src/memory/cpu/tlb.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "arch/memory/cpu/tlb.hpp" - -#include "arch/memory/cpu/control_register.hpp" - -namespace teachos::arch::memory::cpu -{ - auto tlb_flush(paging::virtual_address address) -> void - { - asm volatile("invlpg (%[input])" : /* no output from call */ : [input] "r"(address) : "memory"); - } - - auto tlb_flush_all() -> void - { - write_control_register(cpu::control_register::CR3, read_control_register(cpu::control_register::CR3)); - } -} // namespace teachos::arch::memory::cpu diff --git a/arch/x86_64/src/memory/main.cpp b/arch/x86_64/src/memory/main.cpp index a6f91d9..abc7431 100644 --- a/arch/x86_64/src/memory/main.cpp +++ b/arch/x86_64/src/memory/main.cpp @@ -1,9 +1,9 @@ #include "arch/memory/main.hpp" #include "arch/exception_handling/assert.hpp" +#include "arch/kernel/cpu/control_register.hpp" +#include "arch/kernel/cpu/msr.hpp" #include "arch/memory/allocator/area_frame_allocator.hpp" -#include "arch/memory/cpu/control_register.hpp" -#include "arch/memory/cpu/msr.hpp" #include "arch/memory/heap/heap_allocator.hpp" #include "arch/memory/paging/active_page_table.hpp" #include "arch/memory/paging/kernel_mapper.hpp" -- cgit v1.2.3 From 11db9338dac611ea32e202add5ce5055b54ebb58 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 13 Mar 2025 15:46:16 +0000 Subject: fixup typing and continue adding gdt --- .../descriptor_table/global_descriptor_table.cpp | 17 ++++++++--------- arch/x86_64/src/kernel/cpu/control_register.cpp | 4 ++-- arch/x86_64/src/kernel/cpu/lgdt.cpp | 14 ++++++++++++++ arch/x86_64/src/kernel/cpu/msr.cpp | 4 ++-- arch/x86_64/src/kernel/cpu/ss.cpp | 8 ++++---- arch/x86_64/src/kernel/cpu/tlb.cpp | 6 +++--- arch/x86_64/src/memory/main.cpp | 4 ++-- 7 files changed, 35 insertions(+), 22 deletions(-) create mode 100644 arch/x86_64/src/kernel/cpu/lgdt.cpp (limited to 'arch/x86_64/src') 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 1cba13c..ca3d7ff 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,9 +1,9 @@ -#include "global_descriptor_table.hpp" +#include "arch/context_switching/descriptor_table/global_descriptor_table.hpp" +#include "arch/context_switching/descriptor_table/segment_descriptor.hpp" +#include "arch/kernel/cpu/lgdt.hpp" #include "arch/stl/vector.hpp" -#include "segment_descriptor.hpp" - namespace teachos::arch::context_switching::descriptor_table { auto create_global_descriptor_table() -> global_descriptor_table @@ -43,15 +43,14 @@ namespace teachos::arch::context_switching::descriptor_table return global_descriptor_table; } - auto load_global_descriptor_table(global_descriptor_table_pointer gdt_pointer) -> void - { - // - } - auto initialize_global_descriptor_table() -> global_descriptor_table { global_descriptor_table gdt{create_global_descriptor_table()}; + + // TODO: Second argument does not work yet (because pointer hpp) global_descriptor_table_pointer gdt_pointer{gdt.size() - 1, &gdt}; - load_global_descriptor_table(gdt_pointer); + kernel::cpu::load_global_descriptor_table(gdt_pointer); + + return gdt; } } // namespace teachos::arch::context_switching::descriptor_table \ No newline at end of file diff --git a/arch/x86_64/src/kernel/cpu/control_register.cpp b/arch/x86_64/src/kernel/cpu/control_register.cpp index 3051bae..a39a360 100644 --- a/arch/x86_64/src/kernel/cpu/control_register.cpp +++ b/arch/x86_64/src/kernel/cpu/control_register.cpp @@ -4,7 +4,7 @@ #include -namespace teachos::arch::memory::cpu +namespace teachos::arch::kernel::cpu { auto read_control_register(control_register cr) -> uint64_t { @@ -69,4 +69,4 @@ namespace teachos::arch::memory::cpu auto const cr0 = read_control_register(control_register::CR0); write_control_register(control_register::CR0, static_cast::type>(flag) | cr0); } -} // namespace teachos::arch::memory::cpu +} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/lgdt.cpp b/arch/x86_64/src/kernel/cpu/lgdt.cpp new file mode 100644 index 0000000..cb13aa8 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/lgdt.cpp @@ -0,0 +1,14 @@ +#include "arch/kernel/cpu/lgdt.hpp" + +#include "arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp" + +namespace teachos::arch::kernel::cpu +{ + auto load_global_descriptor_table(context_switching::descriptor_table::global_descriptor_table_pointer gdt_pointer) + -> void + { + // TODO: build lgdt argument from global_descriptor_table_pointer (don't know how yet) + asm volatile("lgdt (%0)" : : "r"(gdt_pointer)); + } + +} // namespace teachos::arch::kernel::cpu \ No newline at end of file diff --git a/arch/x86_64/src/kernel/cpu/msr.cpp b/arch/x86_64/src/kernel/cpu/msr.cpp index 082bca9..6249f8f 100644 --- a/arch/x86_64/src/kernel/cpu/msr.cpp +++ b/arch/x86_64/src/kernel/cpu/msr.cpp @@ -1,6 +1,6 @@ #include "arch/kernel/cpu/msr.hpp" -namespace teachos::arch::memory::cpu +namespace teachos::arch::kernel::cpu { namespace { @@ -28,4 +28,4 @@ namespace teachos::arch::memory::cpu auto const efer = read_msr(IA32_EFER_ADDRESS); write_msr(IA32_EFER_ADDRESS, static_cast::type>(flag) | efer); } -} // namespace teachos::arch::memory::cpu +} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/ss.cpp b/arch/x86_64/src/kernel/cpu/ss.cpp index b7e52e1..9c8dd61 100644 --- a/arch/x86_64/src/kernel/cpu/ss.cpp +++ b/arch/x86_64/src/kernel/cpu/ss.cpp @@ -1,6 +1,6 @@ #include "arch/kernel/cpu/ss.hpp" -namespace teachos::arch::memory::cpu +namespace teachos::arch::kernel::cpu { segment_selector::segment_selector(uint16_t index, std::bitset<1U> table_indicator, std::bitset<2U> requested_privilege_level) @@ -20,14 +20,14 @@ namespace teachos::arch::memory::cpu auto read_ss() -> uint16_t { uint16_t ss; - __asm__("mov %%ss, %0" : "=r"(ss)); + asm volatile("mov %%ss, %0" : "=r"(ss)); return ss; } auto write_ss(segment_selector selector) -> void { uint16_t ss = selector.to_uint16(); - __asm__("mov %0, %%ss" ::"r"(ss)); + asm volatile("mov %0, %%ss" ::"r"(ss)); } -} // namespace teachos::arch::memory::cpu \ No newline at end of file +} // namespace teachos::arch::kernel::cpu \ No newline at end of file diff --git a/arch/x86_64/src/kernel/cpu/tlb.cpp b/arch/x86_64/src/kernel/cpu/tlb.cpp index e753c2c..a09001c 100644 --- a/arch/x86_64/src/kernel/cpu/tlb.cpp +++ b/arch/x86_64/src/kernel/cpu/tlb.cpp @@ -2,9 +2,9 @@ #include "arch/kernel/cpu/control_register.hpp" -namespace teachos::arch::memory::cpu +namespace teachos::arch::kernel::cpu { - auto tlb_flush(paging::virtual_address address) -> void + auto tlb_flush(memory::paging::virtual_address address) -> void { asm volatile("invlpg (%[input])" : /* no output from call */ : [input] "r"(address) : "memory"); } @@ -13,4 +13,4 @@ namespace teachos::arch::memory::cpu { write_control_register(cpu::control_register::CR3, read_control_register(cpu::control_register::CR3)); } -} // namespace teachos::arch::memory::cpu +} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/memory/main.cpp b/arch/x86_64/src/memory/main.cpp index abc7431..a920a20 100644 --- a/arch/x86_64/src/memory/main.cpp +++ b/arch/x86_64/src/memory/main.cpp @@ -38,8 +38,8 @@ namespace teachos::arch::memory auto const memory_information = multiboot::read_multiboot2(); allocator::area_frame_allocator allocator(memory_information); - cpu::set_cr0_bit(memory::cpu::cr0_flags::WRITE_PROTECT); - cpu::set_efer_bit(memory::cpu::efer_flags::NXE); + kernel::cpu::set_cr0_bit(kernel::cpu::cr0_flags::WRITE_PROTECT); + kernel::cpu::set_efer_bit(kernel::cpu::efer_flags::NXE); paging::kernel_mapper kernel(allocator, memory_information); auto & active_table = kernel.remap_kernel(); -- cgit v1.2.3 From f2b9ac8f0f22354241e9b78e47aa7cb94e5ef511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Fri, 14 Mar 2025 14:20:24 +0000 Subject: Fix header recursion problem --- .../descriptor_table/global_descriptor_table.cpp | 7 ++----- arch/x86_64/src/kernel/cpu/lgdt.cpp | 11 +++++++---- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'arch/x86_64/src') 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 ca3d7ff..f4ea61b 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 @@ -45,12 +45,9 @@ namespace teachos::arch::context_switching::descriptor_table auto initialize_global_descriptor_table() -> global_descriptor_table { - global_descriptor_table gdt{create_global_descriptor_table()}; - - // TODO: Second argument does not work yet (because pointer hpp) + decltype(auto) gdt = create_global_descriptor_table(); global_descriptor_table_pointer gdt_pointer{gdt.size() - 1, &gdt}; kernel::cpu::load_global_descriptor_table(gdt_pointer); - return gdt; } -} // namespace teachos::arch::context_switching::descriptor_table \ No newline at end of file +} // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/src/kernel/cpu/lgdt.cpp b/arch/x86_64/src/kernel/cpu/lgdt.cpp index cb13aa8..70a48dd 100644 --- a/arch/x86_64/src/kernel/cpu/lgdt.cpp +++ b/arch/x86_64/src/kernel/cpu/lgdt.cpp @@ -4,11 +4,14 @@ namespace teachos::arch::kernel::cpu { - 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 { // TODO: build lgdt argument from global_descriptor_table_pointer (don't know how yet) - asm volatile("lgdt (%0)" : : "r"(gdt_pointer)); + // asm volatile("lgdt (%0)" : : "r"(gdt_pointer)); + if (gdt_pointer.table_length) + { + } } - -} // namespace teachos::arch::kernel::cpu \ No newline at end of file +} // namespace teachos::arch::kernel::cpu -- cgit v1.2.3 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 --- .../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 +++++++++ 12 files changed, 86 insertions(+), 87 deletions(-) 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 (limited to 'arch/x86_64/src') 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::GRANULARITY | gdt_flags::LENGTH, limit}; + segment_descriptor kernel_code_segment{kernel_code_access_byte, kernel_code_gdt_flags, 0, limit}; // Kernel space data segment access_byte kernel_data_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_KERNEL | - access_byte::CODE_OR_DATA_SEGMENT, - type_field::WRITABLE}; - gdt_flags kernel_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND}; - segment_descriptor kernel_data_segment{kernel_data_access_byte, kernel_data_gdt_flags, 0, 0xFFFFF}; + access_byte::CODE_OR_DATA_SEGMENT | access_byte::WRITABLE}; + gdt_flags kernel_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND, limit}; + segment_descriptor kernel_data_segment{kernel_data_access_byte, kernel_data_gdt_flags, 0, limit}; // User space code segment access_byte user_code_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_USER | - access_byte::CODE_OR_DATA_SEGMENT, - type_field::CODE_SEGMENT | type_field::READABLE}; - gdt_flags user_code_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::LENGTH}; - segment_descriptor user_code_segment{user_code_access_byte, user_code_gdt_flags, 0, 0xFFFFF}; + access_byte::CODE_OR_DATA_SEGMENT | access_byte::CODE_SEGMENT | + access_byte::READABLE}; + gdt_flags user_code_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::LENGTH, limit}; + segment_descriptor user_code_segment{user_code_access_byte, user_code_gdt_flags, 0, limit}; // User space data segment access_byte user_data_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_USER | - access_byte::CODE_OR_DATA_SEGMENT, - type_field::WRITABLE}; - gdt_flags user_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND}; - segment_descriptor user_data_segment{user_data_access_byte, user_data_gdt_flags, 0, 0xFFFFF}; + access_byte::CODE_OR_DATA_SEGMENT | access_byte::WRITABLE}; + gdt_flags user_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND, limit}; + segment_descriptor user_data_segment{user_data_access_byte, user_data_gdt_flags, 0, limit}; stl::vector global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment, user_code_segment, user_data_segment}; @@ -46,8 +46,14 @@ namespace teachos::arch::context_switching::descriptor_table auto initialize_global_descriptor_table() -> global_descriptor_table { decltype(auto) gdt = create_global_descriptor_table(); - global_descriptor_table_pointer gdt_pointer{gdt.size() - 1, &gdt}; + global_descriptor_table_pointer gdt_pointer{static_cast(gdt.size() - 1), &gdt}; kernel::cpu::load_global_descriptor_table(gdt_pointer); + + auto stored_gdt_pointer = kernel::cpu::store_global_descriptor_table(); + arch::exception_handling::assert( + gdt_pointer == stored_gdt_pointer, + "[Global Descriptor Table] Loaded GDTR 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/context_switching/descriptor_table/global_descriptor_table_pointer.cpp b/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table_pointer.cpp new file mode 100644 index 0000000..f552496 --- /dev/null +++ b/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table_pointer.cpp @@ -0,0 +1,12 @@ +#include "arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp" + +namespace teachos::arch::context_switching::descriptor_table +{ + global_descriptor_table_pointer::global_descriptor_table_pointer(uint16_t table_length, + global_descriptor_table * address) + : table_length(table_length) + , address(address) + { + // Nothing to do. + } +} // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp index a743ad2..c1a46a6 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp @@ -5,9 +5,8 @@ namespace teachos::arch::context_switching::descriptor_table segment_descriptor::segment_descriptor(uint128_t flags) : _limit_1(flags << 112U) , _base_1((flags >> 16U) << 88U) - , _access((flags >> 44U) << 80U, (flags >> 40U) << 84U) - , _limit_2((flags >> 48U) << 72U) - , _flag((flags >> 52U) << 72U) + , _access((flags >> 40U) << 80U) + , _flag((flags >> 52U) << 72U, (flags >> 48U) << 72U) , _base_2((flags >> 56U) << 32U) , _reserved(flags >> 96U) { @@ -16,10 +15,9 @@ namespace teachos::arch::context_switching::descriptor_table segment_descriptor::segment_descriptor(access_byte access_byte, gdt_flags flags, uint64_t base, std::bitset<20U> limit) - : _limit_1((limit.to_ulong() << 4U) >> 16U) + : _limit_1(limit.to_ulong()) , _base_1((base << 40U) >> 40U) , _access(access_byte) - , _limit_2(limit.to_ulong() >> 16U) , _flag(flags) , _base_2(base >> 24U) , _reserved(0U) @@ -33,12 +31,7 @@ namespace teachos::arch::context_switching::descriptor_table { return segment_descriptor_type::SYSTEM_SEGMENT; } - - if (_access.get_type_field().contains_flags(type_field::CODE_SEGMENT)) - { - return segment_descriptor_type::CODE_SEGMENT; - } - - return segment_descriptor_type::DATA_SEGMENT; + return _access.contains_flags(access_byte::CODE_SEGMENT) ? segment_descriptor_type::CODE_SEGMENT + : segment_