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
committerMatteo Gmür <matteo.gmuer1@ost.ch>2025-03-15 11:29:26 +0000
commit60ab85044289f4a9a0a84c37bfb2b3938f6ae416 (patch)
treef1b41963d0a28bbe26e4e8f61c8bcc11b4daa000 /arch/x86_64/src
parentf2b9ac8f0f22354241e9b78e47aa7cb94e5ef511 (diff)
downloadteachos-60ab85044289f4a9a0a84c37bfb2b3938f6ae416.tar.xz
teachos-60ab85044289f4a9a0a84c37bfb2b3938f6ae416.zip
Fix size of segment descriptor using bit fields and struct packing
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.cpp33
-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.cpp6
-rw-r--r--arch/x86_64/src/kernel/main.cpp3
-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
9 files changed, 41 insertions, 62 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..cbd230b 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
@@ -10,33 +10,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,7 +45,7 @@ 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);
return gdt;
}
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..cad3ffa 100644
--- a/arch/x86_64/src/kernel/cpu/lgdt.cpp
+++ b/arch/x86_64/src/kernel/cpu/lgdt.cpp
@@ -8,10 +8,6 @@ namespace teachos::arch::kernel::cpu
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] "r"(gdt_pointer));
}
} // namespace teachos::arch::kernel::cpu
diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp
index 4db9599..055b516 100644
--- a/arch/x86_64/src/kernel/main.cpp
+++ b/arch/x86_64/src/kernel/main.cpp
@@ -60,8 +60,7 @@ namespace teachos::arch::kernel
heap_test();
- context_switching::descriptor_table::global_descriptor_table global_descriptor_table{
- context_switching::descriptor_table::initialize_global_descriptor_table()};
+ auto 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)
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