diff options
| author | Fabian Imhof <fabian.imhof@ost.ch> | 2025-05-01 12:25:40 +0000 |
|---|---|---|
| committer | Fabian Imhof <fabian.imhof@ost.ch> | 2025-05-01 12:25:40 +0000 |
| commit | 7c045d8ded72017ff11fd4b9b02148987b944caf (patch) | |
| tree | 5976c4420178cb3e7a4a992f7679ceedd1bb2b34 | |
| parent | 5eb8d63a6ece530cb1d56217a046553b4b96245d (diff) | |
| download | teachos-7c045d8ded72017ff11fd4b9b02148987b944caf.tar.xz teachos-7c045d8ded72017ff11fd4b9b02148987b944caf.zip | |
WIP experiment with converting GDT to 8-Byte entries
14 files changed, 188 insertions, 52 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 71b1946..58afdb5 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -98,6 +98,8 @@ target_sources("_context" PRIVATE "src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp" "src/context_switching/segment_descriptor_table/global_descriptor_table.cpp" "src/context_switching/segment_descriptor_table/segment_descriptor.cpp" + "src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp" + "src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp" "src/context_switching/main.cpp" "src/context_switching/interrupt_descriptor_table/gate_descriptor.cpp" "src/context_switching/interrupt_descriptor_table/idt_flags.cpp" diff --git a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp index 7bfb563..8748448 100644 --- a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp +++ b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp @@ -44,17 +44,13 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table * @brief Constructor. * * @param index Index into the local or global descriptor table. Processor multiplies the index value by 8 (number - * of bytes in 32-bit segment descriptor) and adds the result to the base GDT or LDT address. Because it only - * multiplies by 8, but we are using long mode the constructor additionally multiplies the given value by two. This - * is done because 64-bit segment descriptor are twice as big in size. If we wouldn't multiply by two, index 1 would - * result in the middle between the second part of the null entry and the first part of the code kernel segment and - * therefore be invalid. + * of bytes in 32-bit segment descriptor) and adds the result to the base GDT or LDT address. * @param flags Allows to set flags for the flags field using the unscoped enum contained in this class, used to * allow for direct integer conversion. */ constexpr segment_selector(uint16_t index, uint8_t flags) : _flags(flags) - , _index(index * 2U) + , _index(index) { // Nothing to do. } diff --git a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp index bd69a46..84a24a2 100644 --- a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp +++ b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp @@ -12,7 +12,7 @@ namespace teachos::arch::context_switching::segment_descriptor_table * * @return Reference to the created global_descriptor_table. */ - auto get_or_create_global_descriptor_table() -> global_descriptor_table &; + auto get_or_create_gdt() -> global_descriptor_table &; /** * @brief Updates the GDTR with the created global descriptor table. If it has not been created yet this @@ -21,13 +21,13 @@ namespace teachos::arch::context_switching::segment_descriptor_table * @note This method will only set the GDTR, but for the processor to actually register the change a far jump * has to be executed. This also has to be done before updating the TR. */ - auto update_global_descriptor_table_register() -> void; + auto update_gdtr() -> void; /** * @brief Updates the TR with the created task state segment. If it has not been created yet this * method will create it. * - * @note This method should only be called after update_global_descriptor_table_register() and a far jump has been + * @note This method should only be called after update_gdtr() and a far jump has been * executed. Because before that trying to access the segment will cause an exception. */ auto update_task_state_segment_register() -> void; diff --git a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp index 6fac2a0..c54647d 100644 --- a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp +++ b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp @@ -1,14 +1,24 @@ #ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_POINTER_HPP #define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_POINTER_HPP -#include "arch/context_switching/segment_descriptor_table/segment_descriptor.hpp" +#include "arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp" +#include "arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp" #include "arch/stl/vector.hpp" #include <cstdint> namespace teachos::arch::context_switching::segment_descriptor_table { - using global_descriptor_table = stl::vector<segment_descriptor>; + struct __attribute__((packed, aligned(8))) global_descriptor_table + { + segment_descriptor_base null; + segment_descriptor_base kernel_code; + segment_descriptor_base kernel_data; + segment_descriptor_base user_code; + segment_descriptor_base user_data; + segment_descriptor_base tss_low; + segment_descriptor_extension tss_high; + }; /** * @brief Represents a pointer to the Global Descriptor Table (GDT). @@ -26,7 +36,7 @@ namespace teachos::arch::context_switching::segment_descriptor_table /** * @brief Constructor. */ - global_descriptor_table_pointer(uint16_t table_length, segment_descriptor * address); + global_descriptor_table_pointer(uint16_t table_length, seg_desc * address); /** * @brief Defaulted three-way comparsion operator. @@ -35,7 +45,7 @@ namespace teachos::arch::context_switching::segment_descriptor_table private: uint16_t table_length = {}; ///< The amount of segment descriptor entries in the global descriptor table - 1. - segment_descriptor * address = {}; ///< Non-owning pointer to the GDT base address. + seg_desc * address = {}; ///< Non-owning pointer to the GDT base address. }; } // namespace teachos::arch::context_switching::segment_descriptor_table diff --git a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor.hpp b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor.hpp index 7fe4ecb..ccd604d 100644 --- a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor.hpp +++ b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor.hpp @@ -10,6 +10,12 @@ namespace teachos::arch::context_switching::segment_descriptor_table __extension__ typedef __int128 int128_t; __extension__ typedef unsigned __int128 uint128_t; + struct seg_desc + { + private: + uint64_t : 64; ///< Makes sure the struct is 8-Bytes big + }; + /** * @brief Defines helper function for all states and the actual data the segment descriptor can have. */ @@ -44,6 +50,12 @@ namespace teachos::arch::context_switching::segment_descriptor_table */ segment_descriptor(access_byte access_byte, gdt_flags flags, uint64_t base, std::bitset<20U> limit); + auto get_limit_1() -> uint16_t; + auto get_base_1() -> uint32_t; + auto get_access() -> access_byte; + auto get_flag() -> gdt_flags; + auto get_base_2() -> uint64_t; + /** * @brief Calculates the underlying segment type that this segement descriptor is describing. */ diff --git a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp new file mode 100644 index 0000000..18c9da1 --- /dev/null +++ b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp @@ -0,0 +1,34 @@ +#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_BASE_HPP +#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_BASE_HPP + +#include "arch/context_switching/segment_descriptor_table/access_byte.hpp" +#include "arch/context_switching/segment_descriptor_table/gdt_flags.hpp" +#include "arch/context_switching/segment_descriptor_table/segment_descriptor.hpp" +#include "arch/context_switching/segment_descriptor_table/segment_descriptor_type.hpp" + +namespace teachos::arch::context_switching::segment_descriptor_table +{ + /** + * @brief Defines helper function for all states and the actual data the segment descriptor can have. + */ + struct [[gnu::packed]] segment_descriptor_base : seg_desc + { + /** + * @brief Default Constructor. + */ + segment_descriptor_base() = default; + + /** + * @brief Constructor. + */ + segment_descriptor_base(segment_descriptor segment_descriptor); + + private: + uint16_t _limit_1 = {}; ///< First part of the limit field (0 - 15) + uint32_t _base_1 : 24 = {}; ///< First part of the base field (16 - 39) + access_byte _access = {}; ///< Access byte field (40 - 47) + gdt_flags _flag = {}; ///< Second part of the limit field + Flags field (48 - 55) + }; +} // namespace teachos::arch::context_switching::segment_descriptor_table + +#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_BASE_HPP diff --git a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp new file mode 100644 index 0000000..0b724f2 --- /dev/null +++ b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp @@ -0,0 +1,31 @@ +#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_EXTENSION_HPP +#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_EXTENSION_HPP + +#include "arch/context_switching/segment_descriptor_table/segment_descriptor.hpp" + +#include <cstdint> + +namespace teachos::arch::context_switching::segment_descriptor_table +{ + /** + * @brief Defines helper function for all states and the actual data the segment descriptor can have. + */ + struct [[gnu::packed]] segment_descriptor_extension : seg_desc + { + /** + * @brief Default Constructor. + */ + segment_descriptor_extension() = default; + + /** + * @brief Constructor. + */ + segment_descriptor_extension(segment_descriptor segment_descriptor); + + private: + uint64_t _base_2 : 40 = {}; ///< Second part of the base field (56 - 95) + uint32_t : 32; ///< Reserved field used to ensure this struct is 128 bits big (96 - 127) + }; +} // namespace teachos::arch::context_switching::segment_descriptor_table + +#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_EXTENSION_HPP diff --git a/arch/x86_64/src/context_switching/main.cpp b/arch/x86_64/src/context_switching/main.cpp index 7db9583..5901998 100644 --- a/arch/x86_64/src/context_switching/main.cpp +++ b/arch/x86_64/src/context_switching/main.cpp @@ -29,7 +29,19 @@ namespace teachos::arch::context_switching constexpr context_switching::interrupt_descriptor_table::segment_selector USER_DATA_SEGMENT_SELECTOR{ 4U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; - auto reload_global_descriptor_table_register() -> void { kernel::cpu::call(KERNEL_CODE_POINTER); } + auto reload_gdtr() -> void + { + // asm volatile("pushq $0x8\n\t" // Push new CS + // "lea 1f(%%rip), %%rax\n\t" // Get address of label 1 into RAX + // "pushq %%rax\n\t" // Push return address + // "lretq\n" // Far return (loads CS:RIP) + // "1:\n\t" // Label to return to + // : + // : + // : "rax", "memory"); + + kernel::cpu::call(KERNEL_CODE_POINTER); + } auto user_mode_main() -> void { @@ -83,9 +95,7 @@ namespace teachos::arch::context_switching kernel::cpu::write_msr(IA32_FMASK_ADDRESS, 0U); uint64_t kernel_cs = KERNEL_CODE_SEGMENT_SELECTOR; - // We want to provide the user code segment, but the instruction calculates + 0x10 to fill the - // cs register (See https://www.felixcloutier.com/x86/sysret). - uint64_t user_cs = USER_CODE_SEGMENT_SELECTOR - 0x10; + uint64_t user_cs = KERNEL_CODE_SEGMENT_SELECTOR; uint64_t star_value = (kernel_cs << 32) | (user_cs << 48); kernel::cpu::write_msr(IA32_STAR_ADDRESS, star_value); @@ -102,17 +112,17 @@ namespace teachos::arch::context_switching { kernel::cpu::clear_interrupt_flag(); - segment_descriptor_table::update_global_descriptor_table_register(); + segment_descriptor_table::update_gdtr(); interrupt_descriptor_table::update_interrupt_descriptor_table_register(); - reload_global_descriptor_table_register(); + reload_gdtr(); segment_descriptor_table::update_task_state_segment_register(); kernel::cpu::set_interrupt_flag(); initalized = true; } - descriptor_tables tables = {segment_descriptor_table::get_or_create_global_descriptor_table(), + descriptor_tables tables = {segment_descriptor_table::get_or_create_gdt(), interrupt_descriptor_table::get_or_create_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 a497632..dd22603 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 @@ -1,11 +1,11 @@ #include "arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp" -#include "arch/context_switching/segment_descriptor_table/segment_descriptor.hpp" +#include "arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp" +#include "arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp" #include "arch/context_switching/segment_descriptor_table/task_state_segment.hpp" #include "arch/exception_handling/assert.hpp" #include "arch/kernel/cpu/gdtr.hpp" #include "arch/kernel/cpu/tr.hpp" -#include "arch/stl/vector.hpp" namespace teachos::arch::context_switching::segment_descriptor_table { @@ -26,7 +26,6 @@ namespace teachos::arch::context_switching::segment_descriptor_table } else if (segment_descriptor_type == segment_descriptor_type::DATA_SEGMENT) { - flags |= gdt_flags::UPPER_BOUND; access_level |= access_byte::WRITABLE; } @@ -34,7 +33,7 @@ namespace teachos::arch::context_switching::segment_descriptor_table return segment_descriptor; } - auto create_task_state_segment_descriptor(task_state_segment * tss) -> segment_descriptor + auto create_tss_descriptor(task_state_segment * tss) -> segment_descriptor { constexpr uint64_t TSS_LIMIT = sizeof(task_state_segment) - 1; access_byte const tss_access_byte{access_byte::PRESENT | access_byte::DESCRIPTOR_LEVEL_KERNEL | @@ -45,43 +44,51 @@ namespace teachos::arch::context_switching::segment_descriptor_table return tss_descriptor; } - auto create_global_descriptor_table() -> global_descriptor_table + auto create_gdt() -> global_descriptor_table * { - segment_descriptor const null_segment{0}; - segment_descriptor const kernel_code_segment = - create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_byte::DESCRIPTOR_LEVEL_KERNEL); - segment_descriptor const kernel_data_segment = - create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_byte::DESCRIPTOR_LEVEL_KERNEL); - segment_descriptor const user_code_segment = - create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_byte::DESCRIPTOR_LEVEL_USER); - segment_descriptor const user_data_segment = - create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_byte::DESCRIPTOR_LEVEL_USER); + segment_descriptor_base const null_segment{segment_descriptor{0}}; + segment_descriptor_base const kernel_code_segment{ + create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_byte::DESCRIPTOR_LEVEL_KERNEL)}; + segment_descriptor_base const kernel_data_segment{ + create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_byte::DESCRIPTOR_LEVEL_KERNEL)}; + segment_descriptor_base const user_code_segment{ + create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_byte::DESCRIPTOR_LEVEL_USER)}; + segment_descriptor_base const user_data_segment{ + create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_byte::DESCRIPTOR_LEVEL_USER)}; // Task State Segment needs to be kept alive static auto tss = new task_state_segment(); - 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}; - return global_descriptor_table; - } + segment_descriptor const tss_descriptor = create_tss_descriptor(tss); + segment_descriptor_base const tss_descriptor_base{tss_descriptor}; + segment_descriptor_extension const tss_descriptor_extension{tss_descriptor}; + + decltype(auto) gdt = new global_descriptor_table{}; + gdt->null = null_segment; + gdt->kernel_code = kernel_code_segment; + gdt->kernel_data = kernel_data_segment; + gdt->user_code = user_code_segment; + gdt->user_data = user_data_segment; + gdt->tss_low = tss_descriptor_base; + gdt->tss_high = tss_descriptor_extension; + + return gdt; + }; } // namespace - auto get_or_create_global_descriptor_table() -> global_descriptor_table & + auto get_or_create_gdt() -> global_descriptor_table & { // Global Descriptor Table needs to be kept alive - static global_descriptor_table gdt = create_global_descriptor_table(); - return gdt; + static global_descriptor_table * gdt = create_gdt(); + return *gdt; } - auto update_global_descriptor_table_register() -> void + auto update_gdtr() -> void { - decltype(auto) gdt = get_or_create_global_descriptor_table(); + decltype(auto) gdt = get_or_create_gdt(); // 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.data()}; + global_descriptor_table_pointer gdt_pointer{static_cast<uint16_t>((7 * sizeof(seg_desc)) - 1), &gdt.null}; kernel::cpu::load_global_descriptor_table(gdt_pointer); auto const stored_gdt_pointer = kernel::cpu::store_global_descriptor_table(); @@ -92,11 +99,11 @@ namespace teachos::arch::context_switching::segment_descriptor_table auto update_task_state_segment_register() -> void { - decltype(auto) gdt = get_or_create_global_descriptor_table(); + get_or_create_gdt(); // 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 = (gdt.size() - 1) * sizeof(segment_descriptor_table::segment_descriptor); + uint16_t const tss_selector = (7 - 1) * sizeof(segment_descriptor_table::segment_descriptor); kernel::cpu::load_task_register(tss_selector); auto const stored_task_register = kernel::cpu::store_task_register(); 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 a4a5de8..b7d2da4 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 @@ -2,8 +2,7 @@ namespace teachos::arch::context_switching::segment_descriptor_table { - global_descriptor_table_pointer::global_descriptor_table_pointer(uint16_t table_length, - segment_descriptor * address) + global_descriptor_table_pointer::global_descriptor_table_pointer(uint16_t table_length, seg_desc * address) : table_length(table_length) , address(address) { diff --git a/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor.cpp index 74f93b2..e74156b 100644 --- a/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor.cpp +++ b/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor.cpp @@ -32,4 +32,15 @@ namespace teachos::arch::context_switching::segment_descriptor_table return _access.contains_flags(access_byte::CODE_SEGMENT) ? segment_descriptor_type::CODE_SEGMENT : segment_descriptor_type::DATA_SEGMENT; } + + auto segment_descriptor::get_limit_1() -> uint16_t { return _limit_1; } + + auto segment_descriptor::get_base_1() -> uint32_t { return _base_1; } + + auto segment_descriptor::get_access() -> access_byte { return _access; } + + auto segment_descriptor::get_flag() -> gdt_flags { return _flag; } + + auto segment_descriptor::get_base_2() -> uint64_t { return _base_2; } + } // namespace teachos::arch::context_switching::segment_descriptor_table diff --git a/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp new file mode 100644 index 0000000..f82dbb9 --- /dev/null +++ b/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp @@ -0,0 +1,13 @@ +#include "arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp" + +namespace teachos::arch::context_switching::segment_descriptor_table +{ + segment_descriptor_base::segment_descriptor_base(segment_descriptor segment_descriptor) + : _limit_1(segment_descriptor.get_limit_1()) + , _base_1(segment_descriptor.get_base_1()) + , _access(segment_descriptor.get_access()) + , _flag(segment_descriptor.get_flag()) + { + // Nothing to do + } +} // namespace teachos::arch::context_switching::segment_descriptor_table diff --git a/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp new file mode 100644 index 0000000..b2649d0 --- /dev/null +++ b/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp @@ -0,0 +1,10 @@ +#include "arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp" + +namespace teachos::arch::context_switching::segment_descriptor_table +{ + segment_descriptor_extension::segment_descriptor_extension(segment_descriptor segment_descriptor) + : _base_2(segment_descriptor.get_base_2()) + { + // Nothing to do + } +} // namespace teachos::arch::context_switching::segment_descriptor_table diff --git a/arch/x86_64/src/kernel/cpu/call.cpp b/arch/x86_64/src/kernel/cpu/call.cpp index 98fa248..932d248 100644 --- a/arch/x86_64/src/kernel/cpu/call.cpp +++ b/arch/x86_64/src/kernel/cpu/call.cpp @@ -4,6 +4,7 @@ namespace teachos::arch::kernel::cpu { auto call(far_pointer pointer) -> void { - asm volatile("rex64 lcall *%[input]" : /* no output from call */ : [input] "m"(pointer)); + // asm volatile("rex64 lcall *%[input]" : /* no output from call */ : [input] "m"(pointer)); + asm volatile("ljmp *%0" : : "m"(pointer)); } } // namespace teachos::arch::kernel::cpu |
