diff options
3 files changed, 27 insertions, 25 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 21a76e8..b338d9d 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 @@ -34,44 +34,41 @@ namespace teachos::arch::context_switching::descriptor_table access_level_bitset |= access_byte::WRITABLE; } - uint64_t base = 0x0; - std::bitset<20U> limit{0xFFFFF}; - access_byte access_byte{access_level_bitset}; - gdt_flags gdt_flags{gdt_flags_bitset, limit}; - segment_descriptor code_segment{access_byte, gdt_flags, base, limit}; - + uint64_t const base = 0x0; + std::bitset<20U> const limit{0xFFFFF}; + access_byte const access_byte{access_level_bitset}; + gdt_flags const gdt_flags{gdt_flags_bitset, limit}; + segment_descriptor const code_segment{access_byte, gdt_flags, base, limit}; return code_segment; } auto create_global_descriptor_table() -> global_descriptor_table { - segment_descriptor null_segment{0}; - segment_descriptor kernel_code_segment = + segment_descriptor const null_segment{0}; + segment_descriptor const kernel_code_segment = create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_level::KERNEL); - segment_descriptor kernel_data_segment = + segment_descriptor const kernel_data_segment = create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_level::KERNEL); - segment_descriptor user_code_segment = + segment_descriptor const user_code_segment = create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_level::USER); - segment_descriptor user_data_segment = + segment_descriptor const 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); + segment_descriptor const 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, tss_descriptor}; + global_descriptor_table const global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment, + user_code_segment, user_data_segment, tss_descriptor}; return global_descriptor_table; } auto create_task_state_segment_descriptor(task_state_segment * tss) -> segment_descriptor { - std::bitset<20U> limit{0xFFFFF}; - access_byte tss_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_KERNEL | - 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}; + access_byte const tss_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_KERNEL | + access_byte::TASK_STATE_SEGMENT_AVAILABLE}; + gdt_flags const tss_gdt_flags{0U, TSS_LIMIT}; + segment_descriptor const tss_descriptor{tss_access_byte, tss_gdt_flags, reinterpret_cast<uint64_t>(tss), TSS_LIMIT}; return tss_descriptor; } @@ -80,11 +77,10 @@ namespace teachos::arch::context_switching::descriptor_table // 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}; kernel::cpu::load_global_descriptor_table(gdt_pointer); - auto stored_gdt_pointer = kernel::cpu::store_global_descriptor_table(); + auto const 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."); @@ -93,7 +89,7 @@ namespace teachos::arch::context_switching::descriptor_table 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(); + 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."); 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 3e93823..2385c58 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 @@ -15,7 +15,7 @@ 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()) - , _base_1((base << 40U) >> 40U) + , _base_1(base) , _access(access_byte) , _flag(flags) , _base_2(base >> 24U) diff --git a/arch/x86_64/src/kernel/cpu/tr.cpp b/arch/x86_64/src/kernel/cpu/tr.cpp index d0e037f..e281189 100644 --- a/arch/x86_64/src/kernel/cpu/tr.cpp +++ b/arch/x86_64/src/kernel/cpu/tr.cpp @@ -11,6 +11,12 @@ namespace teachos::arch::kernel::cpu auto load_task_register(uint16_t gdt_offset) -> void { - asm volatile("ltr %[input]" : /* no output from call */ : [input] "r"(gdt_offset)); + // asm volatile("ltr %[input]" : /* no output from call */ : [input] "R"(gdt_offset)); + // https://www.scs.stanford.edu/05au-cs240c/lab/i386/s07_03.htm + asm volatile("mov %[input], %%ax\n" + "ltr %%ax\n" + : /* no output from call */ + : [input] "r"(gdt_offset) + : "ax"); } } // namespace teachos::arch::kernel::cpu |
