aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src')
-rw-r--r--arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp27
-rw-r--r--arch/x86_64/src/kernel/cpu/tr.cpp4
-rw-r--r--arch/x86_64/src/kernel/main.cpp2
3 files changed, 15 insertions, 18 deletions
diff --git a/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp b/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp
index 77bd3e9..21a76e8 100644
--- a/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp
+++ b/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp
@@ -54,9 +54,12 @@ namespace teachos::arch::context_switching::descriptor_table
create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_level::USER);
segment_descriptor user_data_segment =
create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_level::USER);
+ // Task State Segment needs to be kept alive
+ static auto tss = new task_state_segment();
+ segment_descriptor tss_descriptor = create_task_state_segment_descriptor(tss);
- global_descriptor_table global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment,
- user_code_segment, user_data_segment};
+ global_descriptor_table global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment,
+ user_code_segment, user_data_segment, tss_descriptor};
return global_descriptor_table;
}
@@ -67,20 +70,15 @@ namespace teachos::arch::context_switching::descriptor_table
access_byte::TASK_STATE_SEGMENT_AVAILABLE};
gdt_flags tss_gdt_flags{0U, limit};
uint64_t tss_address = reinterpret_cast<uint64_t>(tss);
- constexpr uint64_t tss_limit = sizeof(task_state_segment) - 1;
- segment_descriptor tss_descriptor{tss_access_byte, tss_gdt_flags, tss_address, tss_limit};
-
+ constexpr uint64_t TSS_LIMIT = sizeof(task_state_segment) - 1;
+ segment_descriptor tss_descriptor{tss_access_byte, tss_gdt_flags, tss_address, TSS_LIMIT};
return tss_descriptor;
}
- auto initialize_global_descriptor_table() -> global_descriptor_table
+ auto initialize_global_descriptor_table() -> global_descriptor_table &
{
- auto gdt = create_global_descriptor_table();
-
- // Add TSS segment descriptor to GDT
- auto tss = new task_state_segment();
- auto tss_descriptor = create_task_state_segment_descriptor(tss);
- gdt.push_back(tss_descriptor);
+ // Global Descriptor Table needs to be kept alive
+ static auto gdt = create_global_descriptor_table();
// Load GDT into GDTR
global_descriptor_table_pointer gdt_pointer{static_cast<uint16_t>(gdt.size() - 1), &gdt};
@@ -91,14 +89,13 @@ namespace teachos::arch::context_switching::descriptor_table
gdt_pointer == stored_gdt_pointer,
"[Global Descriptor Table] Loaded GDTR value is not the same as the stored value.");
- // Load Task Register (LTR) using the index of TSS descriptor
- uint16_t tss_selector = (gdt.size() - 1) * sizeof(segment_descriptor);
+ // Calculate the offset of the gdt in bytes to the TSS descriptor
+ uint16_t const tss_selector = (gdt.size() - 1) * sizeof(segment_descriptor);
kernel::cpu::load_task_register(tss_selector);
auto stored_task_register = kernel::cpu::store_task_register();
arch::exception_handling::assert(tss_selector == stored_task_register,
"[Global Descriptor Table] Loaded TR value is not the same as the stored value.");
-
return gdt;
}
} // namespace teachos::arch::context_switching::descriptor_table
diff --git a/arch/x86_64/src/kernel/cpu/tr.cpp b/arch/x86_64/src/kernel/cpu/tr.cpp
index ad38d09..d0e037f 100644
--- a/arch/x86_64/src/kernel/cpu/tr.cpp
+++ b/arch/x86_64/src/kernel/cpu/tr.cpp
@@ -5,12 +5,12 @@ namespace teachos::arch::kernel::cpu
auto store_task_register() -> uint16_t
{
uint16_t current_value{};
- asm("str %[output]" : [output] "=m"(current_value));
+ asm("str %[output]" : [output] "=r"(current_value));
return current_value;
}
auto load_task_register(uint16_t gdt_offset) -> void
{
- asm volatile("ltr %[input]" : /* no output from call */ : [input] "m"(gdt_offset));
+ asm volatile("ltr %[input]" : /* no output from call */ : [input] "r"(gdt_offset));
}
} // namespace teachos::arch::kernel::cpu
diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp
index c1e134a..da6d6d3 100644
--- a/arch/x86_64/src/kernel/main.cpp
+++ b/arch/x86_64/src/kernel/main.cpp
@@ -60,7 +60,7 @@ namespace teachos::arch::kernel
heap_test();
- auto global_descriptor_table = context_switching::descriptor_table::initialize_global_descriptor_table();
+ decltype(auto) global_descriptor_table = context_switching::descriptor_table::initialize_global_descriptor_table();
(void)global_descriptor_table.at(1);
video::vga::text::write("GDT FILLED", video::vga::text::common_attributes::green_on_black);
}