From b8a0024ee71a64ec0e87a1e2d0c0c7280dc954e6 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 13 Mar 2025 09:36:00 +0000 Subject: create GDT and fix segment descriptor bit order --- arch/x86_64/src/kernel/main.cpp | 50 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 472aed5..d3938ed 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,9 +1,11 @@ #include "arch/kernel/main.hpp" +#include "arch/context_switching/descriptor_table/segment_descriptor.hpp" #include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/main.hpp" #include "arch/memory/multiboot/reader.hpp" +#include "arch/stl/vector.hpp" #include "arch/video/vga/text.hpp" namespace teachos::arch::kernel @@ -57,5 +59,53 @@ namespace teachos::arch::kernel memory::heap::global_heap_allocator::register_heap_allocator(memory::heap::heap_allocator_type::LINKED_LIST); heap_test(); + + using context_switching::descriptor_table::access_byte; + using context_switching::descriptor_table::gdt_flags; + using context_switching::descriptor_table::segment_descriptor; + using context_switching::descriptor_table::segment_descriptor_type; + using context_switching::descriptor_table::type_field; + + segment_descriptor null_segment{0}; + + // 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}; + + // 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}; + + // 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}; + + // 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}; + + stl::vector global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment, + user_code_segment, user_data_segment}; + + decltype(auto) x = global_descriptor_table.at(1); + if (global_descriptor_table.size() == 0) + { + } + if (x.get_segment_type() == segment_descriptor_type::CODE_SEGMENT) + { + } + video::vga::text::write("GDT FILLED", video::vga::text::common_attributes::green_on_black); } } // namespace teachos::arch::kernel -- cgit v1.2.3 From 2e4cbd473ff3bb7ac7371af39becf830b4fb753b Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 13 Mar 2025 14:05:45 +0000 Subject: IN_PROGRESS implement gdt initialization --- arch/x86_64/src/kernel/cpu/control_register.cpp | 72 +++++++++++++++++++++++++ arch/x86_64/src/kernel/cpu/msr.cpp | 31 +++++++++++ arch/x86_64/src/kernel/cpu/ss.cpp | 33 ++++++++++++ arch/x86_64/src/kernel/cpu/tlb.cpp | 16 ++++++ arch/x86_64/src/kernel/main.cpp | 44 ++------------- 5 files changed, 156 insertions(+), 40 deletions(-) create mode 100644 arch/x86_64/src/kernel/cpu/control_register.cpp create mode 100644 arch/x86_64/src/kernel/cpu/msr.cpp create mode 100644 arch/x86_64/src/kernel/cpu/ss.cpp create mode 100644 arch/x86_64/src/kernel/cpu/tlb.cpp (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/control_register.cpp b/arch/x86_64/src/kernel/cpu/control_register.cpp new file mode 100644 index 0000000..3051bae --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/control_register.cpp @@ -0,0 +1,72 @@ +#include "arch/kernel/cpu/control_register.hpp" + +#include "arch/exception_handling/panic.hpp" + +#include + +namespace teachos::arch::memory::cpu +{ + auto read_control_register(control_register cr) -> uint64_t + { + uint64_t current_value; + switch (cr) + { + case control_register::CR0: + asm volatile("mov %%cr0, %[output]" : [output] "=r"(current_value)); + break; + case control_register::CR2: + asm volatile("mov %%cr2, %[output]" : [output] "=r"(current_value)); + break; + case control_register::CR3: + asm volatile("mov %%cr3, %[output]" : [output] "=r"(current_value)); + break; + case control_register::CR4: + asm volatile("mov %%cr4, %[output]" : [output] "=r"(current_value)); + break; + default: + exception_handling::panic("[Control Register] Attempted to read non-existent or reserved control register"); + break; + } + return current_value; + } + + auto write_control_register(control_register cr, uint64_t new_value) -> void + { + switch (cr) + { + case control_register::CR0: + asm volatile("mov %[input], %%cr0" + : /* no output from call */ + : [input] "r"(new_value) + : "memory"); + break; + case control_register::CR2: + asm volatile("mov %[input], %%cr2" + : /* no output from call */ + : [input] "r"(new_value) + : "memory"); + break; + case control_register::CR3: + asm volatile("mov %[input], %%cr3" + : /* no output from call */ + : [input] "r"(new_value) + : "memory"); + break; + case control_register::CR4: + asm volatile("mov %[input], %%cr4" + : /* no output from call */ + : [input] "r"(new_value) + : "memory"); + break; + default: + exception_handling::panic("[Control Register] Attempted to write non-existent or reserved control register"); + break; + } + } + + auto set_cr0_bit(cr0_flags flag) -> void + { + auto const cr0 = read_control_register(control_register::CR0); + write_control_register(control_register::CR0, static_cast::type>(flag) | cr0); + } +} // namespace teachos::arch::memory::cpu diff --git a/arch/x86_64/src/kernel/cpu/msr.cpp b/arch/x86_64/src/kernel/cpu/msr.cpp new file mode 100644 index 0000000..082bca9 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/msr.cpp @@ -0,0 +1,31 @@ +#include "arch/kernel/cpu/msr.hpp" + +namespace teachos::arch::memory::cpu +{ + namespace + { + auto constexpr IA32_EFER_ADDRESS = 0xC0000080; + } + + auto read_msr(uint32_t msr) -> uint64_t + { + uint32_t low, high; + asm volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); + return (static_cast(high) << 32) | low; + } + + auto write_msr(uint32_t msr, uint64_t value) -> void + { + uint32_t low = value & 0xFFFFFFFF; + uint32_t high = value >> 32; + asm volatile("wrmsr" + : /* no output from call */ + : "c"(msr), "a"(low), "d"(high)); + } + + auto set_efer_bit(efer_flags flag) -> void + { + auto const efer = read_msr(IA32_EFER_ADDRESS); + write_msr(IA32_EFER_ADDRESS, static_cast::type>(flag) | efer); + } +} // namespace teachos::arch::memory::cpu diff --git a/arch/x86_64/src/kernel/cpu/ss.cpp b/arch/x86_64/src/kernel/cpu/ss.cpp new file mode 100644 index 0000000..b7e52e1 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/ss.cpp @@ -0,0 +1,33 @@ +#include "arch/kernel/cpu/ss.hpp" + +namespace teachos::arch::memory::cpu +{ + segment_selector::segment_selector(uint16_t index, std::bitset<1U> table_indicator, + std::bitset<2U> requested_privilege_level) + : index(index) + , table_indicator(table_indicator) + , requested_privilege_level(requested_privilege_level) + { + // Nothing to do + } + + auto segment_selector::to_uint16() const -> uint16_t + { + return static_cast((index << 3) | (table_indicator.to_ulong() << 2) | + requested_privilege_level.to_ulong()); + } + + auto read_ss() -> uint16_t + { + uint16_t ss; + __asm__("mov %%ss, %0" : "=r"(ss)); + return ss; + } + + auto write_ss(segment_selector selector) -> void + { + uint16_t ss = selector.to_uint16(); + __asm__("mov %0, %%ss" ::"r"(ss)); + } + +} // namespace teachos::arch::memory::cpu \ No newline at end of file diff --git a/arch/x86_64/src/kernel/cpu/tlb.cpp b/arch/x86_64/src/kernel/cpu/tlb.cpp new file mode 100644 index 0000000..e753c2c --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/tlb.cpp @@ -0,0 +1,16 @@ +#include "arch/kernel/cpu/tlb.hpp" + +#include "arch/kernel/cpu/control_register.hpp" + +namespace teachos::arch::memory::cpu +{ + auto tlb_flush(paging::virtual_address address) -> void + { + asm volatile("invlpg (%[input])" : /* no output from call */ : [input] "r"(address) : "memory"); + } + + auto tlb_flush_all() -> void + { + write_control_register(cpu::control_register::CR3, read_control_register(cpu::control_register::CR3)); + } +} // namespace teachos::arch::memory::cpu diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index d3938ed..4db9599 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,6 +1,6 @@ #include "arch/kernel/main.hpp" -#include "arch/context_switching/descriptor_table/segment_descriptor.hpp" +#include "arch/context_switching/descriptor_table/global_descriptor_table.hpp" #include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/main.hpp" @@ -60,50 +60,14 @@ namespace teachos::arch::kernel heap_test(); - using context_switching::descriptor_table::access_byte; - using context_switching::descriptor_table::gdt_flags; - using context_switching::descriptor_table::segment_descriptor; - using context_switching::descriptor_table::segment_descriptor_type; - using context_switching::descriptor_table::type_field; - - segment_descriptor null_segment{0}; - - // 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}; - - // 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}; - - // 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}; - - // 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}; - - stl::vector global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment, - user_code_segment, user_data_segment}; + 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() == segment_descriptor_type::CODE_SEGMENT) + if (x.get_segment_type() == context_switching::descriptor_table::segment_descriptor_type::CODE_SEGMENT) { } video::vga::text::write("GDT FILLED", video::vga::text::common_attributes::green_on_black); -- cgit v1.2.3 From 11db9338dac611ea32e202add5ce5055b54ebb58 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 13 Mar 2025 15:46:16 +0000 Subject: fixup typing and continue adding gdt --- arch/x86_64/src/kernel/cpu/control_register.cpp | 4 ++-- arch/x86_64/src/kernel/cpu/lgdt.cpp | 14 ++++++++++++++ arch/x86_64/src/kernel/cpu/msr.cpp | 4 ++-- arch/x86_64/src/kernel/cpu/ss.cpp | 8 ++++---- arch/x86_64/src/kernel/cpu/tlb.cpp | 6 +++--- 5 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 arch/x86_64/src/kernel/cpu/lgdt.cpp (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/control_register.cpp b/arch/x86_64/src/kernel/cpu/control_register.cpp index 3051bae..a39a360 100644 --- a/arch/x86_64/src/kernel/cpu/control_register.cpp +++ b/arch/x86_64/src/kernel/cpu/control_register.cpp @@ -4,7 +4,7 @@ #include -namespace teachos::arch::memory::cpu +namespace teachos::arch::kernel::cpu { auto read_control_register(control_register cr) -> uint64_t { @@ -69,4 +69,4 @@ namespace teachos::arch::memory::cpu auto const cr0 = read_control_register(control_register::CR0); write_control_register(control_register::CR0, static_cast::type>(flag) | cr0); } -} // namespace teachos::arch::memory::cpu +} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/lgdt.cpp b/arch/x86_64/src/kernel/cpu/lgdt.cpp new file mode 100644 index 0000000..cb13aa8 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/lgdt.cpp @@ -0,0 +1,14 @@ +#include "arch/kernel/cpu/lgdt.hpp" + +#include "arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp" + +namespace teachos::arch::kernel::cpu +{ + auto load_global_descriptor_table(context_switching::descriptor_table::global_descriptor_table_pointer gdt_pointer) + -> void + { + // TODO: build lgdt argument from global_descriptor_table_pointer (don't know how yet) + asm volatile("lgdt (%0)" : : "r"(gdt_pointer)); + } + +} // namespace teachos::arch::kernel::cpu \ No newline at end of file diff --git a/arch/x86_64/src/kernel/cpu/msr.cpp b/arch/x86_64/src/kernel/cpu/msr.cpp index 082bca9..6249f8f 100644 --- a/arch/x86_64/src/kernel/cpu/msr.cpp +++ b/arch/x86_64/src/kernel/cpu/msr.cpp @@ -1,6 +1,6 @@ #include "arch/kernel/cpu/msr.hpp" -namespace teachos::arch::memory::cpu +namespace teachos::arch::kernel::cpu { namespace { @@ -28,4 +28,4 @@ namespace teachos::arch::memory::cpu auto const efer = read_msr(IA32_EFER_ADDRESS); write_msr(IA32_EFER_ADDRESS, static_cast::type>(flag) | efer); } -} // namespace teachos::arch::memory::cpu +} // 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 b7e52e1..9c8dd61 100644 --- a/arch/x86_64/src/kernel/cpu/ss.cpp +++ b/arch/x86_64/src/kernel/cpu/ss.cpp @@ -1,6 +1,6 @@ #include "arch/kernel/cpu/ss.hpp" -namespace teachos::arch::memory::cpu +namespace teachos::arch::kernel::cpu { segment_selector::segment_selector(uint16_t index, std::bitset<1U> table_indicator, std::bitset<2U> requested_privilege_level) @@ -20,14 +20,14 @@ namespace teachos::arch::memory::cpu auto read_ss() -> uint16_t { uint16_t ss; - __asm__("mov %%ss, %0" : "=r"(ss)); + asm volatile("mov %%ss, %0" : "=r"(ss)); return ss; } auto write_ss(segment_selector selector) -> void { uint16_t ss = selector.to_uint16(); - __asm__("mov %0, %%ss" ::"r"(ss)); + asm volatile("mov %0, %%ss" ::"r"(ss)); } -} // namespace teachos::arch::memory::cpu \ No newline at end of file +} // namespace teachos::arch::kernel::cpu \ No newline at end of file diff --git a/arch/x86_64/src/kernel/cpu/tlb.cpp b/arch/x86_64/src/kernel/cpu/tlb.cpp index e753c2c..a09001c 100644 --- a/arch/x86_64/src/kernel/cpu/tlb.cpp +++ b/arch/x86_64/src/kernel/cpu/tlb.cpp @@ -2,9 +2,9 @@ #include "arch/kernel/cpu/control_register.hpp" -namespace teachos::arch::memory::cpu +namespace teachos::arch::kernel::cpu { - auto tlb_flush(paging::virtual_address address) -> void + auto tlb_flush(memory::paging::virtual_address address) -> void { asm volatile("invlpg (%[input])" : /* no output from call */ : [input] "r"(address) : "memory"); } @@ -13,4 +13,4 @@ namespace teachos::arch::memory::cpu { write_control_register(cpu::control_register::CR3, read_control_register(cpu::control_register::CR3)); } -} // namespace teachos::arch::memory::cpu +} // namespace teachos::arch::kernel::cpu -- cgit v1.2.3 From f2b9ac8f0f22354241e9b78e47aa7cb94e5ef511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Fri, 14 Mar 2025 14:20:24 +0000 Subject: Fix header recursion problem --- arch/x86_64/src/kernel/cpu/lgdt.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/lgdt.cpp b/arch/x86_64/src/kernel/cpu/lgdt.cpp index cb13aa8..70a48dd 100644 --- a/arch/x86_64/src/kernel/cpu/lgdt.cpp +++ b/arch/x86_64/src/kernel/cpu/lgdt.cpp @@ -4,11 +4,14 @@ namespace teachos::arch::kernel::cpu { - auto load_global_descriptor_table(context_switching::descriptor_table::global_descriptor_table_pointer gdt_pointer) + 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)); + // asm volatile("lgdt (%0)" : : "r"(gdt_pointer)); + if (gdt_pointer.table_length) + { + } } - -} // namespace teachos::arch::kernel::cpu \ No newline at end of file +} // namespace teachos::arch::kernel::cpu -- cgit v1.2.3 From 2b8e6e7e10f084a9a9ba5c0b79a041f4d1ac459b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Sat, 15 Mar 2025 11:29:26 +0000 Subject: implement loading of gdtr register --- arch/x86_64/src/kernel/cpu/lgdt.cpp | 13 ++++++++----- arch/x86_64/src/kernel/cpu/ss.cpp | 8 ++++---- arch/x86_64/src/kernel/main.cpp | 13 +++---------- 3 files changed, 15 insertions(+), 19 deletions(-) (limited to 'arch/x86_64/src/kernel') 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 -- cgit v1.2.3 From 36758071881088b27a52cee4e5653f6cf6a79a78 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Sun, 16 Mar 2025 12:41:09 +0000 Subject: start implementing TSS --- arch/x86_64/src/kernel/cpu/gdtr.cpp | 20 ++++++++++++++++++++ arch/x86_64/src/kernel/cpu/lgdt.cpp | 20 -------------------- arch/x86_64/src/kernel/cpu/tr.cpp | 17 +++++++++++++++++ arch/x86_64/src/kernel/main.cpp | 1 - 4 files changed, 37 insertions(+), 21 deletions(-) create mode 100644 arch/x86_64/src/kernel/cpu/gdtr.cpp delete mode 100644 arch/x86_64/src/kernel/cpu/lgdt.cpp create mode 100644 arch/x86_64/src/kernel/cpu/tr.cpp (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/gdtr.cpp b/arch/x86_64/src/kernel/cpu/gdtr.cpp new file mode 100644 index 0000000..2fe3a99 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/gdtr.cpp @@ -0,0 +1,20 @@ +#include "arch/kernel/cpu/gdtr.hpp" + +#include "arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp" + +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 + { + 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/lgdt.cpp b/arch/x86_64/src/kernel/cpu/lgdt.cpp deleted file mode 100644 index 386914f..0000000 --- a/arch/x86_64/src/kernel/cpu/lgdt.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "arch/kernel/cpu/lgdt.hpp" - -#include "arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp" - -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 - { - 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/tr.cpp b/arch/x86_64/src/kernel/cpu/tr.cpp new file mode 100644 index 0000000..a28b9fc --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/tr.cpp @@ -0,0 +1,17 @@ +#include "arch/kernel/cpu/tr.hpp" + +namespace teachos::arch::kernel::cpu +{ + auto store_task_register() -> uint16_t + { + uint16_t current_value{}; + asm("str %[output]" : [output] "=m"(current_value)); + return current_value; + } + + // TODO: Is this really correct? + auto load_task_register(uint16_t gdt_offset) -> void + { + asm volatile("ltr %[input]" : /* no output from call */ : [input] "m"(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 2c0b6c8..c1e134a 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,7 +1,6 @@ #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" -- cgit v1.2.3 From 37cb71ca7771a28835e3ed6aa5ed0797c9ba50fa Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Sun, 16 Mar 2025 12:50:14 +0000 Subject: add comment --- arch/x86_64/src/kernel/cpu/tr.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/tr.cpp b/arch/x86_64/src/kernel/cpu/tr.cpp index a28b9fc..ad38d09 100644 --- a/arch/x86_64/src/kernel/cpu/tr.cpp +++ b/arch/x86_64/src/kernel/cpu/tr.cpp @@ -9,7 +9,6 @@ namespace teachos::arch::kernel::cpu return current_value; } - // TODO: Is this really correct? auto load_task_register(uint16_t gdt_offset) -> void { asm volatile("ltr %[input]" : /* no output from call */ : [input] "m"(gdt_offset)); -- cgit v1.2.3 From c56a8a74bc4e9662469db33a85c12586f202985a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 17 Mar 2025 09:38:39 +0000 Subject: Fix issue in vector --- arch/x86_64/src/kernel/cpu/tr.cpp | 4 ++-- arch/x86_64/src/kernel/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/x86_64/src/kernel') 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); } -- cgit v1.2.3 From 3c01f820a064f3120a46aa3afdd9f88ce9e00db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 17 Mar 2025 14:51:24 +0000 Subject: Debug and adjust load task register assembly call. WIP --- arch/x86_64/src/kernel/cpu/tr.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch/x86_64/src/kernel') 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 -- cgit v1.2.3 From b6ee8bec7ed23fd0c544f67f735e96b2bfe67682 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 20 Mar 2025 15:30:18 +0000 Subject: begin implementation of IDT --- arch/x86_64/src/kernel/cpu/idtr.cpp | 19 +++++++++++++++++++ arch/x86_64/src/kernel/cpu/if.cpp | 5 +++++ arch/x86_64/src/kernel/cpu/jmp.cpp | 16 ++++++++++++++++ arch/x86_64/src/kernel/main.cpp | 10 ++++++---- 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 arch/x86_64/src/kernel/cpu/idtr.cpp create mode 100644 arch/x86_64/src/kernel/cpu/if.cpp create mode 100644 arch/x86_64/src/kernel/cpu/jmp.cpp (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/idtr.cpp b/arch/x86_64/src/kernel/cpu/idtr.cpp new file mode 100644 index 0000000..bbf34cb --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/idtr.cpp @@ -0,0 +1,19 @@ +#include "arch/kernel/cpu/idtr.hpp" + +#include "arch/context_switching/descriptor_table/interrupt_descriptor_table_pointer.hpp" + +namespace teachos::arch::kernel::cpu +{ + auto store_global_descriptor_table() -> context_switching::descriptor_table::global_descriptor_table_pointer + { + context_switching::descriptor_table::interrupt_descriptor_table_pointer current_value{}; + asm("sidt %[output]" : [output] "=m"(current_value)); + return current_value; + } + + auto load_interrupt_descriptor_table( + context_switching::descriptor_table::interrupt_descriptor_table_pointer const & idt_pointer) -> void + { + asm volatile("lidt %[input]" : /* no output from call */ : [input] "m"(idt_pointer)); + } +} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/if.cpp b/arch/x86_64/src/kernel/cpu/if.cpp new file mode 100644 index 0000000..2a25df5 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/if.cpp @@ -0,0 +1,5 @@ +namespace teachos::arch::kernel::cpu +{ + auto set_interrupt_flag() -> void { asm volatile("sti"); } + +} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/jmp.cpp b/arch/x86_64/src/kernel/cpu/jmp.cpp new file mode 100644 index 0000000..009981b --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/jmp.cpp @@ -0,0 +1,16 @@ +#include "arch/kernel/cpu/jmp.hpp" + +namespace teachos::arch::kernel::cpu +{ + auto jmp(uint64_t address) -> void + { + asm volatile("jmp *%[input]" : /* no output from call */ : [input] "r"(address)); + } + + auto jmp(uint64_t segment, uint64_t offset) -> void + { + far_pointer far_pointer = {offset, static_cast(segment)}; + asm volatile("jmp *%0" : : "m"(far_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 da6d6d3..9433558 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,6 +1,9 @@ #include "arch/kernel/main.hpp" -#include "arch/context_switching/descriptor_table/global_descriptor_table.hpp" +#include "arch/boot/pointers.hpp" +#include "arch/context_switching/descriptor_table/initialization.hpp" +#include "arch/kernel/cpu/if.hpp" +#include "arch/kernel/cpu/jmp.hpp" #include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/main.hpp" @@ -60,8 +63,7 @@ namespace teachos::arch::kernel heap_test(); - 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); + decltype(auto) descriptor_tables = context_switching::descriptor_table::initialize_descriptor_tables(); + (void)descriptor_tables; } } // namespace teachos::arch::kernel -- cgit v1.2.3 From ccb47845d99e098c183f596cd1a3eb1db5c676da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Tue, 25 Mar 2025 12:04:43 +0000 Subject: Adjust file structure and fix compilation issues --- arch/x86_64/src/kernel/cpu/gdtr.cpp | 11 +++++------ arch/x86_64/src/kernel/cpu/idtr.cpp | 9 ++++----- arch/x86_64/src/kernel/main.cpp | 4 ++-- 3 files changed, 11 insertions(+), 13 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/gdtr.cpp b/arch/x86_64/src/kernel/cpu/gdtr.cpp index 2fe3a99..74a4e1c 100644 --- a/arch/x86_64/src/kernel/cpu/gdtr.cpp +++ b/arch/x86_64/src/kernel/cpu/gdtr.cpp @@ -1,19 +1,18 @@ #include "arch/kernel/cpu/gdtr.hpp" -#include "arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp" +#include "arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp" namespace teachos::arch::kernel::cpu { - auto store_global_descriptor_table() -> context_switching::descriptor_table::global_descriptor_table_pointer + auto store_global_descriptor_table() -> context_switching::segment_descriptor_table::global_descriptor_table_pointer { - context_switching::descriptor_table::global_descriptor_table_pointer current_value{}; + context_switching::segment_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 + auto load_global_descriptor_table( + context_switching::segment_descriptor_table::global_descriptor_table_pointer const & gdt_pointer) -> void { asm volatile("lgdt %[input]" : /* no output from call */ : [input] "m"(gdt_pointer)); } diff --git a/arch/x86_64/src/kernel/cpu/idtr.cpp b/arch/x86_64/src/kernel/cpu/idtr.cpp index bbf34cb..7aa20c1 100644 --- a/arch/x86_64/src/kernel/cpu/idtr.cpp +++ b/arch/x86_64/src/kernel/cpu/idtr.cpp @@ -1,18 +1,17 @@ #include "arch/kernel/cpu/idtr.hpp" -#include "arch/context_switching/descriptor_table/interrupt_descriptor_table_pointer.hpp" - namespace teachos::arch::kernel::cpu { - auto store_global_descriptor_table() -> context_switching::descriptor_table::global_descriptor_table_pointer + auto store_interrupt_descriptor_table() + -> context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer { - context_switching::descriptor_table::interrupt_descriptor_table_pointer current_value{}; + context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer current_value{}; asm("sidt %[output]" : [output] "=m"(current_value)); return current_value; } auto load_interrupt_descriptor_table( - context_switching::descriptor_table::interrupt_descriptor_table_pointer const & idt_pointer) -> void + context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer const & idt_pointer) -> void { asm volatile("lidt %[input]" : /* no output from call */ : [input] "m"(idt_pointer)); } diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 9433558..7782d30 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,7 +1,7 @@ #include "arch/kernel/main.hpp" #include "arch/boot/pointers.hpp" -#include "arch/context_switching/descriptor_table/initialization.hpp" +#include "arch/context_switching/main.hpp" #include "arch/kernel/cpu/if.hpp" #include "arch/kernel/cpu/jmp.hpp" #include "arch/memory/heap/bump_allocator.hpp" @@ -63,7 +63,7 @@ namespace teachos::arch::kernel heap_test(); - decltype(auto) descriptor_tables = context_switching::descriptor_table::initialize_descriptor_tables(); + decltype(auto) descriptor_tables = context_switching::initialize_descriptor_tables(); (void)descriptor_tables; } } // namespace teachos::arch::kernel -- cgit v1.2.3 From 66fefaeb16bcbc4eae5ce5256ae76f51a155cded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Tue, 25 Mar 2025 16:58:24 +0000 Subject: Implement idtr structure and document possible flags. --- arch/x86_64/src/kernel/cpu/ss.cpp | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/ss.cpp b/arch/x86_64/src/kernel/cpu/ss.cpp index 1f28e7f..0978eca 100644 --- a/arch/x86_64/src/kernel/cpu/ss.cpp +++ b/arch/x86_64/src/kernel/cpu/ss.cpp @@ -2,32 +2,15 @@ namespace teachos::arch::kernel::cpu { - segment_selector::segment_selector(uint16_t index, std::bitset<1U> table_indicator, - std::bitset<2U> requested_privilege_level) - : index(index) - , table_indicator(table_indicator) - , requested_privilege_level(requested_privilege_level) + auto read_ss() -> context_switching::interrupt_descriptor_table::segment_selector { - // Nothing to do - } - - auto segment_selector::to_uint16() const -> uint16_t - { - return static_cast((index << 3) | (table_indicator.to_ulong() << 2) | - requested_privilege_level.to_ulong()); - } - - auto read_ss() -> uint16_t - { - uint16_t segment_selector; - asm volatile("mov %%ss, %[output]" : [output] "=r"(segment_selector)); + context_switching::interrupt_descriptor_table::segment_selector segment_selector{}; + asm volatile("mov %%ss, %[output]" : [output] "=m"(segment_selector)); return segment_selector; } - auto write_ss(segment_selector selector) -> void + auto write_ss(context_switching::interrupt_descriptor_table::segment_selector selector) -> void { - uint16_t ss = selector.to_uint16(); - asm volatile("mov %[input], %%ss" : /* no output from call */ : [input] "r"(ss)); + asm volatile("mov %[input], %%ss" : /* no output from call */ : [input] "m"(selector)); } - -} // namespace teachos::arch::kernel::cpu \ No newline at end of file +} // namespace teachos::arch::kernel::cpu -- cgit v1.2.3 From a6c5f6a273d0c5c4161f600fca6d4fe49858c23c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Thu, 27 Mar 2025 09:40:32 +0000 Subject: Attempt to fix crash in far jump. WIP does not return from call to assembler method --- arch/x86_64/src/kernel/cpu/if.cpp | 2 ++ arch/x86_64/src/kernel/cpu/jmp.cpp | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/if.cpp b/arch/x86_64/src/kernel/cpu/if.cpp index 2a25df5..60a90a3 100644 --- a/arch/x86_64/src/kernel/cpu/if.cpp +++ b/arch/x86_64/src/kernel/cpu/if.cpp @@ -2,4 +2,6 @@ namespace teachos::arch::kernel::cpu { auto set_interrupt_flag() -> void { asm volatile("sti"); } + auto clear_interrupt_flag() -> void { asm volatile("cli"); } + } // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/jmp.cpp b/arch/x86_64/src/kernel/cpu/jmp.cpp index 009981b..205c4a9 100644 --- a/arch/x86_64/src/kernel/cpu/jmp.cpp +++ b/arch/x86_64/src/kernel/cpu/jmp.cpp @@ -7,10 +7,8 @@ namespace teachos::arch::kernel::cpu asm volatile("jmp *%[input]" : /* no output from call */ : [input] "r"(address)); } - auto jmp(uint64_t segment, uint64_t offset) -> void + auto jmp(far_pointer pointer) -> void { - far_pointer far_pointer = {offset, static_cast(segment)}; - asm volatile("jmp *%0" : : "m"(far_pointer)); + asm volatile("jmp *%[input]" : /* no output from call */ : [input] "m"(pointer)); } - } // namespace teachos::arch::kernel::cpu -- cgit v1.2.3 From 9ddfcd02413a93718e8cde53f9ba5a96a5b29b8f Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 27 Mar 2025 14:02:05 +0000 Subject: update long jump handling --- arch/x86_64/src/kernel/cpu/jmp.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/jmp.cpp b/arch/x86_64/src/kernel/cpu/jmp.cpp index 205c4a9..78b65f4 100644 --- a/arch/x86_64/src/kernel/cpu/jmp.cpp +++ b/arch/x86_64/src/kernel/cpu/jmp.cpp @@ -7,8 +7,10 @@ namespace teachos::arch::kernel::cpu asm volatile("jmp *%[input]" : /* no output from call */ : [input] "r"(address)); } - auto jmp(far_pointer pointer) -> void - { - asm volatile("jmp *%[input]" : /* no output from call */ : [input] "m"(pointer)); - } + // auto jmp(far_pointer pointer) -> void + // { + // asm volatile("ljmp $[segment_selector],$[address]" + // : /* no output from call */ + // : [segment_selector] "m"(pointer.selector), [address] "m"(pointer.offset)); + // } } // namespace teachos::arch::kernel::cpu -- cgit v1.2.3 From e0eae9b9e905a1842b333823bfdb7c253cda8d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Fri, 28 Mar 2025 09:59:09 +0000 Subject: Revert "update long jump handling" This reverts commit 9ddfcd02413a93718e8cde53f9ba5a96a5b29b8f. --- arch/x86_64/src/kernel/cpu/jmp.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/jmp.cpp b/arch/x86_64/src/kernel/cpu/jmp.cpp index 78b65f4..205c4a9 100644 --- a/arch/x86_64/src/kernel/cpu/jmp.cpp +++ b/arch/x86_64/src/kernel/cpu/jmp.cpp @@ -7,10 +7,8 @@ namespace teachos::arch::kernel::cpu asm volatile("jmp *%[input]" : /* no output from call */ : [input] "r"(address)); } - // auto jmp(far_pointer pointer) -> void - // { - // asm volatile("ljmp $[segment_selector],$[address]" - // : /* no output from call */ - // : [segment_selector] "m"(pointer.selector), [address] "m"(pointer.offset)); - // } + auto jmp(far_pointer pointer) -> void + { + asm volatile("jmp *%[input]" : /* no output from call */ : [input] "m"(pointer)); + } } // namespace teachos::arch::kernel::cpu -- cgit v1.2.3 From 437c3554f9a86b6347d97f5e2a82543c1e068b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Fri, 28 Mar 2025 10:52:25 +0000 Subject: Attempt to fix ljmp. Might not be possible in Long mode --- arch/x86_64/src/kernel/cpu/jmp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/jmp.cpp b/arch/x86_64/src/kernel/cpu/jmp.cpp index 205c4a9..0c94693 100644 --- a/arch/x86_64/src/kernel/cpu/jmp.cpp +++ b/arch/x86_64/src/kernel/cpu/jmp.cpp @@ -2,13 +2,13 @@ namespace teachos::arch::kernel::cpu { - auto jmp(uint64_t address) -> void + auto jmp(std::size_t address) -> void { asm volatile("jmp *%[input]" : /* no output from call */ : [input] "r"(address)); } auto jmp(far_pointer pointer) -> void { - asm volatile("jmp *%[input]" : /* no output from call */ : [input] "m"(pointer)); + asm volatile("rex64 ljmp *%[input]" : /* no output from call */ : [input] "m"(pointer)); } } // namespace teachos::arch::kernel::cpu -- cgit v1.2.3 From abe7bd7480c8f4e1e30b9f0f3b98966222817f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 31 Mar 2025 10:38:53 +0000 Subject: Clean up global descriptor table initalization --- arch/x86_64/src/kernel/cpu/jmp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/jmp.cpp b/arch/x86_64/src/kernel/cpu/jmp.cpp index 0c94693..2833219 100644 --- a/arch/x86_64/src/kernel/cpu/jmp.cpp +++ b/arch/x86_64/src/kernel/cpu/jmp.cpp @@ -9,6 +9,6 @@ namespace teachos::arch::kernel::cpu auto jmp(far_pointer pointer) -> void { - asm volatile("rex64 ljmp *%[input]" : /* no output from call */ : [input] "m"(pointer)); + asm volatile("rex64 lcall *%[input]" : /* no output from call */ : [input] "m"(pointer)); } } // namespace teachos::arch::kernel::cpu -- cgit v1.2.3 From a8852f91967a7e55e62e30f5cc07d076092b8b78 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Sat, 5 Apr 2025 15:27:20 +0000 Subject: add wip context switch to user mode --- arch/x86_64/src/kernel/cpu/segment_register.cpp | 34 ++++++++++++++++++++++++ arch/x86_64/src/kernel/cpu/ss.cpp | 16 ----------- arch/x86_64/src/kernel/main.cpp | 35 +++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 arch/x86_64/src/kernel/cpu/segment_register.cpp delete mode 100644 arch/x86_64/src/kernel/cpu/ss.cpp (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/segment_register.cpp b/arch/x86_64/src/kernel/cpu/segment_register.cpp new file mode 100644 index 0000000..f70c558 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/segment_register.cpp @@ -0,0 +1,34 @@ +#include "arch/kernel/cpu/segment_register.hpp" + +#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" + +namespace teachos::arch::kernel::cpu +{ + [[gnu::naked]] + auto reload_segment_registers() -> void + { + asm volatile("xor %rax, %rax\n" + "mov %rax, %ss\n" + "mov %rax, %ds\n" + "mov %rax, %es\n" + "mov %rax, %fs\n" + "mov %rax, %gs\n" + "ret"); + } + + [[gnu::naked]] + auto set_segment_registers(context_switching::interrupt_descriptor_table::segment_selector segment_selector) -> void + { + asm volatile("xor %%rax, %%rax\n" + "mov %[input], %%ax\n" + "mov %%rax, %%ss\n" + "mov %%rax, %%ds\n" + "mov %%rax, %%es\n" + "mov %%rax, %%fs\n" + "mov %%rax, %%gs\n" + "ret" + : /* No output from call */ + : [input] "m"(segment_selector)); + } + +} // 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 deleted file mode 100644 index 0978eca..0000000 --- a/arch/x86_64/src/kernel/cpu/ss.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "arch/kernel/cpu/ss.hpp" - -namespace teachos::arch::kernel::cpu -{ - auto read_ss() -> context_switching::interrupt_descriptor_table::segment_selector - { - context_switching::interrupt_descriptor_table::segment_selector segment_selector{}; - asm volatile("mov %%ss, %[output]" : [output] "=m"(segment_selector)); - return segment_selector; - } - - auto write_ss(context_switching::interrupt_descriptor_table::segment_selector selector) -> void - { - asm volatile("mov %[input], %%ss" : /* no output from call */ : [input] "m"(selector)); - } -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 7782d30..7d4173e 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,9 +1,11 @@ #include "arch/kernel/main.hpp" #include "arch/boot/pointers.hpp" +#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" #include "arch/context_switching/main.hpp" #include "arch/kernel/cpu/if.hpp" #include "arch/kernel/cpu/jmp.hpp" +#include "arch/kernel/cpu/segment_register.hpp" #include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/main.hpp" @@ -49,6 +51,23 @@ namespace teachos::arch::kernel delete test9; } + [[gnu::naked]] + auto push_code_segment(context_switching::interrupt_descriptor_table::segment_selector segment_selector) -> void + { + asm volatile("push %%rbp\n" + "push %[input]" + : /* No output from call */ + : [input] "m"(segment_selector)); + } + + [[gnu::naked]] + auto iret() -> void + { + asm volatile("iret" + : /* No output from call */ + : /* No input to call */); + } + auto main() -> void { video::vga::text::clear(); @@ -64,6 +83,22 @@ namespace teachos::arch::kernel heap_test(); decltype(auto) descriptor_tables = context_switching::initialize_descriptor_tables(); + + // - Clear NT flag in EFLAGS register (for far return) + + // - Push return instruction pointer + // - Push return code segment selector + context_switching::interrupt_descriptor_table::segment_selector user_code_segment_selector{ + 3U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; + push_code_segment(user_code_segment_selector); + + context_switching::interrupt_descriptor_table::segment_selector user_data_segment_selector{ + 4U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; + kernel::cpu::set_segment_registers(user_data_segment_selector); + + // IRET + iret(); + (void)descriptor_tables; } } // namespace teachos::arch::kernel -- cgit v1.2.3 From 350aedae0e50749f9821ac7dc6b8316cf35f24bb Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Sun, 6 Apr 2025 07:47:27 +0000 Subject: wip context switch in asm --- arch/x86_64/src/kernel/main.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 7d4173e..52799f0 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -52,12 +52,24 @@ namespace teachos::arch::kernel } [[gnu::naked]] - auto push_code_segment(context_switching::interrupt_descriptor_table::segment_selector segment_selector) -> void + auto push_code_segment(context_switching::interrupt_descriptor_table::segment_selector segment_selector_a, + context_switching::interrupt_descriptor_table::segment_selector segment_selector_b) -> void { asm volatile("push %%rbp\n" "push %[input]" : /* No output from call */ - : [input] "m"(segment_selector)); + : [input] "m"(segment_selector_a)); + asm volatile("mov %[input], %%ax\n" + "mov %%ax, %%ss\n" + "mov %%ax, %%ds\n" + "mov %%ax, %%es\n" + "mov %%ax, %%fs\n" + "mov %%ax, %%gs" + : /* No output from call */ + : [input] "m"(segment_selector_b)); + asm volatile("iret" + : /* No output from call */ + : /* No input to call */); } [[gnu::naked]] @@ -88,16 +100,13 @@ namespace teachos::arch::kernel // - Push return instruction pointer // - Push return code segment selector - context_switching::interrupt_descriptor_table::segment_selector user_code_segment_selector{ - 3U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; - push_code_segment(user_code_segment_selector); - - context_switching::interrupt_descriptor_table::segment_selector user_data_segment_selector{ - 4U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; - kernel::cpu::set_segment_registers(user_data_segment_selector); + // context_switching::interrupt_descriptor_table::segment_selector user_code_segment_selector{ + // 3U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; + // context_switching::interrupt_descriptor_table::segment_selector user_data_segment_selector{ + // 4U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; + // push_code_segment(user_code_segment_selector, user_data_segment_selector); - // IRET - iret(); + boot::context_switch(); (void)descriptor_tables; } -- cgit v1.2.3 From 8a23a47425162894141f4eac488fb1f1bb3f7dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 7 Apr 2025 15:42:38 +0000 Subject: Fix naming from jmp to call for Far Call --- arch/x86_64/src/kernel/cpu/call.cpp | 9 +++++++++ arch/x86_64/src/kernel/cpu/jmp.cpp | 14 -------------- arch/x86_64/src/kernel/main.cpp | 1 - 3 files changed, 9 insertions(+), 15 deletions(-) create mode 100644 arch/x86_64/src/kernel/cpu/call.cpp delete mode 100644 arch/x86_64/src/kernel/cpu/jmp.cpp (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/call.cpp b/arch/x86_64/src/kernel/cpu/call.cpp new file mode 100644 index 0000000..98fa248 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/call.cpp @@ -0,0 +1,9 @@ +#include "arch/kernel/cpu/call.hpp" + +namespace teachos::arch::kernel::cpu +{ + auto call(far_pointer pointer) -> void + { + asm volatile("rex64 lcall *%[input]" : /* no output from call */ : [input] "m"(pointer)); + } +} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/jmp.cpp b/arch/x86_64/src/kernel/cpu/jmp.cpp deleted file mode 100644 index 2833219..0000000 --- a/arch/x86_64/src/kernel/cpu/jmp.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "arch/kernel/cpu/jmp.hpp" - -namespace teachos::arch::kernel::cpu -{ - auto jmp(std::size_t address) -> void - { - asm volatile("jmp *%[input]" : /* no output from call */ : [input] "r"(address)); - } - - auto jmp(far_pointer pointer) -> void - { - asm volatile("rex64 lcall *%[input]" : /* no output from call */ : [input] "m"(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 52799f0..7787f30 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -4,7 +4,6 @@ #include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" #include "arch/context_switching/main.hpp" #include "arch/kernel/cpu/if.hpp" -#include "arch/kernel/cpu/jmp.hpp" #include "arch/kernel/cpu/segment_register.hpp" #include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/global_heap_allocator.hpp" -- cgit v1.2.3 From 862d7f33414132cb73f7f3968250a071d78c191b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Thu, 10 Apr 2025 08:10:10 +0000 Subject: Replace iret with iretq (64-bit) --- arch/x86_64/src/kernel/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 7787f30..daaf216 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -66,7 +66,7 @@ namespace teachos::arch::kernel "mov %%ax, %%gs" : /* No output from call */ : [input] "m"(segment_selector_b)); - asm volatile("iret" + asm volatile("iretq" : /* No output from call */ : /* No input to call */); } @@ -74,7 +74,7 @@ namespace teachos::arch::kernel [[gnu::naked]] auto iret() -> void { - asm volatile("iret" + asm volatile("iretq" : /* No output from call */ : /* No input to call */); } -- cgit v1.2.3 From 62d7fa83e831e84ea851d97b5c957146880ad69a Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 10 Apr 2025 10:28:46 +0000 Subject: move context_switch function into cpp code --- arch/x86_64/src/kernel/cpu/segment_register.cpp | 1 - arch/x86_64/src/kernel/main.cpp | 76 ++++++++++++++----------- 2 files changed, 44 insertions(+), 33 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/segment_register.cpp b/arch/x86_64/src/kernel/cpu/segment_register.cpp index f70c558..d7857dd 100644 --- a/arch/x86_64/src/kernel/cpu/segment_register.cpp +++ b/arch/x86_64/src/kernel/cpu/segment_register.cpp @@ -21,7 +21,6 @@ namespace teachos::arch::kernel::cpu { asm volatile("xor %%rax, %%rax\n" "mov %[input], %%ax\n" - "mov %%rax, %%ss\n" "mov %%rax, %%ds\n" "mov %%rax, %%es\n" "mov %%rax, %%fs\n" diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index daaf216..ac2591e 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -50,33 +50,48 @@ namespace teachos::arch::kernel delete test9; } - [[gnu::naked]] - auto push_code_segment(context_switching::interrupt_descriptor_table::segment_selector segment_selector_a, - context_switching::interrupt_descriptor_table::segment_selector segment_selector_b) -> void + auto return_function() -> void { - asm volatile("push %%rbp\n" - "push %[input]" - : /* No output from call */ - : [input] "m"(segment_selector_a)); - asm volatile("mov %[input], %%ax\n" - "mov %%ax, %%ss\n" - "mov %%ax, %%ds\n" - "mov %%ax, %%es\n" - "mov %%ax, %%fs\n" - "mov %%ax, %%gs" - : /* No output from call */ - : [input] "m"(segment_selector_b)); - asm volatile("iretq" - : /* No output from call */ - : /* No input to call */); + video::vga::text::write("User Mode!!!", video::vga::text::common_attributes::green_on_black); } + /** + * @brief Switch context into the mode defined in the segment selectors. + * + * Setup the stack IRETQ expects to switch the mode: + * 1. push data selector + * 2. push current stack pointer + * 3. push eflags + * 4. push code segment selector + * 5. push return address + * + * @param data_segment + * @param code_segment + * @param address + */ [[gnu::naked]] - auto iret() -> void + auto switch_context(context_switching::interrupt_descriptor_table::segment_selector data_segment, + context_switching::interrupt_descriptor_table::segment_selector code_segment, uint64_t address) + -> void { - asm volatile("iretq" - : /* No output from call */ - : /* No input to call */); + asm volatile("mov %[data_segment], %%rax\n" + "mov %%rax, %%ds\n" + "mov %%rax, %%es\n" + "mov %%rax, %%fs\n" + "mov %%rax, %%gs\n" + "mov %%rsp, %%rax\n" + + "push %[data_segment]\n" + "push %%rax\n" + "pushfq\n" + "push %[code_segment]\n" + "mov %[return_function], %%rax\n" + "push %%rax\n" + + "iretq\n" + : + : [data_segment] "m"(data_segment), [code_segment] "m"(code_segment), [return_function] "r"(address) + : "rax"); } auto main() -> void @@ -95,17 +110,14 @@ namespace teachos::arch::kernel decltype(auto) descriptor_tables = context_switching::initialize_descriptor_tables(); - // - Clear NT flag in EFLAGS register (for far return) - - // - Push return instruction pointer - // - Push return code segment selector - // context_switching::interrupt_descriptor_table::segment_selector user_code_segment_selector{ - // 3U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; - // context_switching::interrupt_descriptor_table::segment_selector user_data_segment_selector{ - // 4U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; - // push_code_segment(user_code_segment_selector, user_data_segment_selector); + context_switching::interrupt_descriptor_table::segment_selector user_code_segment_selector{ + 3U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; + context_switching::interrupt_descriptor_table::segment_selector user_data_segment_selector{ + 4U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; - boot::context_switch(); + cpu::set_segment_registers(user_data_segment_selector); + switch_context(user_data_segment_selector, user_code_segment_selector, + reinterpret_cast(&return_function)); (void)descriptor_tables; } -- cgit v1.2.3 From dff78de795a89c181e9c94b26db2f16988e8f4d6 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 10 Apr 2025 12:11:55 +0000 Subject: move context_switch function and environment into different directory --- arch/x86_64/src/kernel/cpu/segment_register.cpp | 9 ++++ arch/x86_64/src/kernel/main.cpp | 56 +------------------------ 2 files changed, 11 insertions(+), 54 deletions(-) (limited to 'arch/x86_64/src/kernel') diff --git a/arch/x86_64/src/kernel/cpu/segment_register.cpp b/arch/x86_64/src/kernel/cpu/segment_register.cpp index d7857dd..9fb7433 100644 --- a/arch/x86_64/src/kernel/cpu/segment_register.cpp +++ b/arch/x86_64/src/kernel/cpu/segment_register.cpp @@ -30,4 +30,13 @@ namespace teachos::arch::kernel::cpu : [input] "m"(segment_selector)); } + auto read_code_segment_register() -> context_switching::interrupt_descriptor_table::segment_selector + { + context_switching::interrupt_descriptor_table::segment_selector current_value; + asm volatile("mov %%cs, %[output]" : [output] "=r"(current_value)); + return current_value; + } + + auto validate_segment_registers() -> context_switching::interrupt_descriptor_table::segment_selector {} + } // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index ac2591e..b6906