diff options
| author | Fabian Imhof <fabian.imhof@ost.ch> | 2025-03-29 09:30:50 +0100 |
|---|---|---|
| committer | Fabian Imhof <fabian.imhof@ost.ch> | 2025-03-29 09:30:50 +0100 |
| commit | 98be1b722f17e77880e8c0b0f464a9ba31230fc4 (patch) | |
| tree | aa693a6f6edc717a1f3e184141d0ee1c150c57d7 /arch/x86_64/src/context_switching | |
| parent | 437c3554f9a86b6347d97f5e2a82543c1e068b05 (diff) | |
| parent | fbd1ebe4f7c5985554fdca7c7fc05de15d47dd3a (diff) | |
| download | teachos-98be1b722f17e77880e8c0b0f464a9ba31230fc4.tar.xz teachos-98be1b722f17e77880e8c0b0f464a9ba31230fc4.zip | |
Merge branch 'fmorgner/patch-context-switching' into 'feat_inital_context_switching'
Fix GDT and CS reload
See merge request teachos/kernel!5
Diffstat (limited to 'arch/x86_64/src/context_switching')
3 files changed, 18 insertions, 17 deletions
diff --git a/arch/x86_64/src/context_switching/main.cpp b/arch/x86_64/src/context_switching/main.cpp index 5d19f23..a5bd3fb 100644 --- a/arch/x86_64/src/context_switching/main.cpp +++ b/arch/x86_64/src/context_switching/main.cpp @@ -13,22 +13,21 @@ namespace teachos::arch::context_switching decltype(auto) global_descriptor_table = segment_descriptor_table::initialize_global_descriptor_table(); decltype(auto) interrupt_descriptor_table = interrupt_descriptor_table::initialize_interrupt_descriptor_table(); - interrupt_descriptor_table::segment_selector segment_selector{ - 1U, interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_KERNEL}; - kernel::cpu::far_pointer pointer{boot::reload_segment_register, segment_selector}; - kernel::cpu::jmp(pointer); + kernel::cpu::far_pointer pointer{&boot::reload_segment_register, 1 * sizeof(segment_descriptor_table::segment_descriptor)}; + asm volatile("rex64 lcall *%[far_function_pointer]" : : [far_function_pointer] "m" (pointer)); - // Load task state segment descriptor from the last element in the global descriptor table, done by calculating - // offset in bytes to the start of the segment descriptor (5 * 16) = 80 - uint16_t const tss_selector = - (global_descriptor_table.size() - 1) * sizeof(segment_descriptor_table::segment_descriptor); - kernel::cpu::load_task_register(tss_selector); + // // Load task state segment descriptor from the last element in the global descriptor table, done by calculating + // // offset in bytes to the start of the segment descriptor (5 * 16) = 80 + // uint16_t const tss_selector = + // (global_descriptor_table.size() - 1) * sizeof(segment_descriptor_table::segment_descriptor); + // kernel::cpu::load_task_register(tss_selector); - auto const 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."); + // auto const 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."); - kernel::cpu::set_interrupt_flag(); + // FIXME: We currently cannot enable interrupts, since for some reason, we will later run into what looks like a GP. Maybe because no IDT is loaded? Maybe our boot code segment is not set up correctly? + // kernel::cpu::set_interrupt_flag(); descriptor_tables tables = {global_descriptor_table, interrupt_descriptor_table}; return tables; diff --git a/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp index e6a489c..37ee778 100644 --- a/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp +++ b/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp @@ -20,12 +20,14 @@ namespace teachos::arch::context_switching::segment_descriptor_table uint8_t gdt_flags_bits = gdt_flags::GRANULARITY; if (segment_descriptor_type == segment_descriptor_type::CODE_SEGMENT) { - gdt_flags_bits |= gdt_flags::LENGTH; + gdt_flags_bits |= gdt_flags::LONG_MODE; access_level_bits |= access_byte::CODE_SEGMENT | access_byte::READABLE; } else if (segment_descriptor_type == segment_descriptor_type::DATA_SEGMENT) { - gdt_flags_bits |= gdt_flags::UPPER_BOUND; + gdt_flags_bits |= 1 << 2; + // FIXME: Look at those bit flags, something seems off. + // gdt_flags_bits |= gdt_flags::UPPER_BOUND; access_level_bits |= access_byte::WRITABLE; } @@ -78,7 +80,7 @@ namespace teachos::arch::context_switching::segment_descriptor_table // Calculate the size of the gdt in bytes - 1. This subtraction occurs because the maximum value of Size is 65535, // while the GDT can be up to 65536 bytes in length (8192 entries). Further, no GDT can have a size of 0 bytes. global_descriptor_table_pointer gdt_pointer{static_cast<uint16_t>((gdt.size() * sizeof(segment_descriptor)) - 1), - &gdt}; + gdt.data()}; kernel::cpu::load_global_descriptor_table(gdt_pointer); auto const stored_gdt_pointer = kernel::cpu::store_global_descriptor_table(); diff --git a/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp index 132565f..a4a5de8 100644 --- a/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp +++ b/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp @@ -3,7 +3,7 @@ namespace teachos::arch::context_switching::segment_descriptor_table { global_descriptor_table_pointer::global_descriptor_table_pointer(uint16_t table_length, - global_descriptor_table * address) + segment_descriptor * address) : table_length(table_length) , address(address) { |
