aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/context_switching
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2025-03-15 11:29:26 +0000
committerFabian Imhof <fabian.imhof@ost.ch>2025-03-15 12:03:23 +0000
commit2b8e6e7e10f084a9a9ba5c0b79a041f4d1ac459b (patch)
tree04f77a457517c8c36e22dead8261191e560eae6d /arch/x86_64/src/context_switching
parentf2b9ac8f0f22354241e9b78e47aa7cb94e5ef511 (diff)
downloadteachos-2b8e6e7e10f084a9a9ba5c0b79a041f4d1ac459b.tar.xz
teachos-2b8e6e7e10f084a9a9ba5c0b79a041f4d1ac459b.zip
implement loading of gdtr register
Diffstat (limited to 'arch/x86_64/src/context_switching')
-rw-r--r--arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp10
-rw-r--r--arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp14
-rw-r--r--arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp40
-rw-r--r--arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table_pointer.cpp12
-rw-r--r--arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp17
-rw-r--r--arch/x86_64/src/context_switching/descriptor_table/type_field.cpp12
6 files changed, 54 insertions, 51 deletions
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<segment_descriptor> 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<uint16_t>(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_descriptor_type::DATA_SEGMENT;
}
} // 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
deleted file mode 100644
index d967a97..0000000
--- a/arch/x86_64/src/context_switching/descriptor_table/type_field.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#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