aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64
diff options
context:
space:
mode:
authorFabian Imhof <fabian.imhof@ost.ch>2025-05-01 12:25:40 +0000
committerFabian Imhof <fabian.imhof@ost.ch>2025-05-01 12:25:40 +0000
commit7c045d8ded72017ff11fd4b9b02148987b944caf (patch)
tree5976c4420178cb3e7a4a992f7679ceedd1bb2b34 /arch/x86_64
parent5eb8d63a6ece530cb1d56217a046553b4b96245d (diff)
downloadteachos-7c045d8ded72017ff11fd4b9b02148987b944caf.tar.xz
teachos-7c045d8ded72017ff11fd4b9b02148987b944caf.zip
WIP experiment with converting GDT to 8-Byte entries
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/CMakeLists.txt2
-rw-r--r--arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp8
-rw-r--r--arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp6
-rw-r--r--arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp18
-rw-r--r--arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor.hpp12
-rw-r--r--arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp34
-rw-r--r--arch/x86_64/include/arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp31
-rw-r--r--arch/x86_64/src/context_switching/main.cpp24
-rw-r--r--arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp65
-rw-r--r--arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp3
-rw-r--r--arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor.cpp11
-rw-r--r--arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp13
-rw-r--r--arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp10
-rw-r--r--arch/x86_64/src/kernel/cpu/call.cpp3
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