aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
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
parentf2b9ac8f0f22354241e9b78e47aa7cb94e5ef511 (diff)
downloadteachos-2b8e6e7e10f084a9a9ba5c0b79a041f4d1ac459b.tar.xz
teachos-2b8e6e7e10f084a9a9ba5c0b79a041f4d1ac459b.zip
implement loading of gdtr register
Diffstat (limited to 'arch/x86_64/src')
-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
-rw-r--r--arch/x86_64/src/kernel/cpu/lgdt.cpp13
-rw-r--r--arch/x86_64/src/kernel/cpu/ss.cpp8
-rw-r--r--arch/x86_64/src/kernel/main.cpp13
-rw-r--r--arch/x86_64/src/memory/heap/linked_list_allocator.cpp2
-rw-r--r--arch/x86_64/src/stl/mutex.cpp (renamed from arch/x86_64/src/shared/mutex.cpp)6
11 files changed, 73 insertions, 74 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
diff --git a/arch/x86_64/src/kernel/cpu/lgdt.cpp b/arch/x86_64/src/kernel/cpu/lgdt.cpp
index 70a48dd..386914f 100644
--- a/arch/x86_64/src/kernel/cpu/lgdt.cpp
+++ b/arch/x86_64/src/kernel/cpu/lgdt.cpp
@@ -4,14 +4,17 @@
namespace teachos::arch::kernel::cpu
{
+ auto store_global_descriptor_table() -> context_switching::descriptor_table::global_descriptor_table_pointer
+ {
+ context_switching::descriptor_table::global_descriptor_table_pointer current_value{};
+ asm("sgdt %[output]" : [output] "=m"(current_value));
+ return current_value;
+ }
+
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));
- if (gdt_pointer.table_length)
- {
- }
+ asm volatile("lgdt %[input]" : /* no output from call */ : [input] "m"(gdt_pointer));
}
} // 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 9c8dd61..1f28e7f 100644
--- a/arch/x86_64/src/kernel/cpu/ss.cpp
+++ b/arch/x86_64/src/kernel/cpu/ss.cpp
@@ -19,15 +19,15 @@ namespace teachos::arch::kernel::cpu
auto read_ss() -> uint16_t
{
- uint16_t ss;
- asm volatile("mov %%ss, %0" : "=r"(ss));
- return ss;
+ uint16_t segment_selector;
+ asm volatile("mov %%ss, %[output]" : [output] "=r"(segment_selector));
+ return segment_selector;
}
auto write_ss(segment_selector selector) -> void
{
uint16_t ss = selector.to_uint16();
- asm volatile("mov %0, %%ss" ::"r"(ss));
+ asm volatile("mov %[input], %%ss" : /* no output from call */ : [input] "r"(ss));
}
} // namespace teachos::arch::kernel::cpu \ No newline at end of file
diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp
index 4db9599..2c0b6c8 100644
--- a/arch/x86_64/src/kernel/main.cpp
+++ b/arch/x86_64/src/kernel/main.cpp
@@ -1,6 +1,7 @@
#include "arch/kernel/main.hpp"
#include "arch/context_switching/descriptor_table/global_descriptor_table.hpp"
+#include "arch/kernel/cpu/lgdt.hpp"
#include "arch/memory/heap/bump_allocator.hpp"
#include "arch/memory/heap/global_heap_allocator.hpp"
#include "arch/memory/main.hpp"
@@ -60,16 +61,8 @@ namespace teachos::arch::kernel
heap_test();
- 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() == context_switching::descriptor_table::segment_descriptor_type::CODE_SEGMENT)
- {
- }
+ 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);
}
} // namespace teachos::arch::kernel
diff --git a/arch/x86_64/src/memory/heap/linked_list_allocator.cpp b/arch/x86_64/src/memory/heap/linked_list_allocator.cpp
index a824c8a..5101ab2 100644
--- a/arch/x86_64/src/memory/heap/linked_list_allocator.cpp
+++ b/arch/x86_64/src/memory/heap/linked_list_allocator.cpp
@@ -11,7 +11,7 @@ namespace teachos::arch::memory::heap
: heap_start(heap_start)
, heap_end(heap_end)
, first(nullptr)
- , mutex{shared::mutex{}}
+ , mutex{stl::mutex{}}
{
auto const heap_size = heap_end - heap_start;
exception_handling::assert(
diff --git a/arch/x86_64/src/shared/mutex.cpp b/arch/x86_64/src/stl/mutex.cpp
index 6598255..232a11c 100644
--- a/arch/x86_64/src/shared/mutex.cpp
+++ b/arch/x86_64/src/stl/mutex.cpp
@@ -1,6 +1,6 @@
-#include "arch/shared/mutex.hpp"
+#include "arch/stl/mutex.hpp"
-namespace teachos::arch::shared
+namespace teachos::arch::stl
{
auto mutex::lock() -> void
{
@@ -13,4 +13,4 @@ namespace teachos::arch::shared
auto mutex::try_lock() -> bool { return !locked.exchange(true, std::memory_order_acquire); }
auto mutex::unlock() -> void { locked.store(false, std::memory_order_release); }
-} // namespace teachos::arch::shared
+} // namespace teachos::arch::stl