aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/include/arch/boot/pointers.hpp2
-rw-r--r--arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp9
-rw-r--r--arch/x86_64/include/arch/kernel/cpu/if.hpp7
-rw-r--r--arch/x86_64/include/arch/kernel/cpu/jmp.hpp14
-rw-r--r--arch/x86_64/src/boot/boot.s2
-rw-r--r--arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp22
-rw-r--r--arch/x86_64/src/context_switching/main.cpp5
-rw-r--r--arch/x86_64/src/kernel/cpu/if.cpp2
-rw-r--r--arch/x86_64/src/kernel/cpu/jmp.cpp6
9 files changed, 37 insertions, 32 deletions
diff --git a/arch/x86_64/include/arch/boot/pointers.hpp b/arch/x86_64/include/arch/boot/pointers.hpp
index 2a43f22..5bcb792 100644
--- a/arch/x86_64/include/arch/boot/pointers.hpp
+++ b/arch/x86_64/include/arch/boot/pointers.hpp
@@ -11,7 +11,7 @@ namespace teachos::arch::boot
extern "C" size_t const multiboot_information_pointer;
/**
- * @brief Address pointing to the start of the multiboot information structure.
+ * @brief Address pointing to the method that clears all segment registers.
*/
extern "C" size_t const segment_register_reload_pointer;
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 c31e2d0..73cd176 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
@@ -43,7 +43,8 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table
/**
* @brief Constructor.
*
- * @param index Index into the local or global descriptor table.
+ * @param index Index into the local or global descriptor table. Processor multiplies the index value by 16 (number
+ * of bytes in segment descriptor) and adds the result to the base 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.
*/
@@ -66,8 +67,10 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table
auto operator<=>(segment_selector const & other) const -> std::strong_ordering = default;
private:
- uint8_t _flags : 3 = {}; ///< Underlying bits used to read the flags from.
- uint16_t _index : 13 = {}; ///< Index into the local or global descriptor table.
+ uint8_t _flags : 3 = {}; ///< Underlying bits used to read the flags from.
+ uint16_t _index : 13 =
+ {}; ///< Index into the local or global descriptor table. Processor multiplies the index value by 16 (number of
+ ///< bytes in segment descriptor) and adds the result to the base address.
};
} // namespace teachos::arch::context_switching::interrupt_descriptor_table
diff --git a/arch/x86_64/include/arch/kernel/cpu/if.hpp b/arch/x86_64/include/arch/kernel/cpu/if.hpp
index 51f5d9a..48707dc 100644
--- a/arch/x86_64/include/arch/kernel/cpu/if.hpp
+++ b/arch/x86_64/include/arch/kernel/cpu/if.hpp
@@ -9,6 +9,13 @@ namespace teachos::arch::kernel::cpu
*/
auto set_interrupt_flag() -> void;
+ /**
+ * @brief Clears the interrupt flag (IF) in the EFLAGS register.
+ * This will stop the processor to respond to maskable hardware interrupts and needs to be done before changing the
+ * Interrupt Descriptor Table with lidt.
+ */
+ auto clear_interrupt_flag() -> void;
+
} // namespace teachos::arch::kernel::cpu
#endif // TEACHOS_ARCH_X86_64_KERNEL_CPU_IF_HPP
diff --git a/arch/x86_64/include/arch/kernel/cpu/jmp.hpp b/arch/x86_64/include/arch/kernel/cpu/jmp.hpp
index 666174c..5bc7d07 100644
--- a/arch/x86_64/include/arch/kernel/cpu/jmp.hpp
+++ b/arch/x86_64/include/arch/kernel/cpu/jmp.hpp
@@ -1,6 +1,8 @@
#ifndef TEACHOS_ARCH_X86_64_KERNEL_CPU_JMP_HPP
#define TEACHOS_ARCH_X86_64_KERNEL_CPU_JMP_HPP
+#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp"
+
#include <cstdint>
namespace teachos::arch::kernel::cpu
@@ -10,14 +12,15 @@ namespace teachos::arch::kernel::cpu
*/
struct [[gnu::packed]] far_pointer
{
- uint64_t offset; ///< Selector of the segment in which the jump occurs.
- uint16_t segment; ///< Address to jump to within the segment.
+ uint64_t offset; ///< Selector of the segment in which the jump occurs. (0- 63)
+ context_switching::interrupt_descriptor_table::segment_selector
+ selector; ///< Address to jump to within the segment. (64 - 79)
};
/**
* @brief Near jump - A jump to an instruction within the current code segment.
*
- * @param address to jump to.
+ * @param address Address we want to jump to.
*/
auto jmp(uint64_t address) -> void;
@@ -25,10 +28,9 @@ namespace teachos::arch::kernel::cpu
* @brief Far jump - A jump to an instruction located in a different segment than the current code segment but at the
* same privilege level.
*
- * @param segment in which the jump occurs.
- * @param offset to jump to.
+ * @param pointer 64-bit operand size far pointer that we should jump too.
*/
- auto jmp(uint64_t segment, uint64_t offset) -> void;
+ auto jmp(far_pointer pointer) -> void;
} // namespace teachos::arch::kernel::cpu
diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s
index 4fb23e5..35a6121 100644
--- a/arch/x86_64/src/boot/boot.s
+++ b/arch/x86_64/src/boot/boot.s
@@ -366,7 +366,7 @@ segment_register_reload_pointer:
ret
_transition_to_long_mode:
- call segment_register_reload_pointer
+ //call segment_register_reload_pointer
xor %rax, %rax
mov %rax, %ss
diff --git a/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp b/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp
index 0555e4c..ddc098e 100644
--- a/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp
+++ b/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp
@@ -9,22 +9,12 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table
{
auto create_interrupt_descriptor_table() -> interrupt_descriptor_table
{
- interrupt_descriptor_table idt{};
-
- // Define basic exception handlers (at least for CPU exceptions 0x00-0x1F)
- for (uint8_t vector = 0; vector < 32; ++vector)
- {
- uint64_t offset = reinterpret_cast<uint64_t>(default_exception_handler); // Use a real handler function
- segment_selector selector{0U, segment_selector::REQUEST_LEVEL_KERNEL};
- ist_offset ist{0U}; // Default stack offset (can be updated for IST)
- idt_flags flags{idt_flags::DESCRIPTOR_LEVEL_KERNEL | idt_flags::TRAP_GATE};
-
- idt.push_back(gate_descriptor{selector, ist, flags, offset});
- }
-
- // Additional entries for hardware interrupts (IRQs) and syscalls can be added here
-
- return idt;
+ uint64_t offset = 0U;
+ segment_selector selector{0U, segment_selector::REQUEST_LEVEL_KERNEL};
+ ist_offset ist{0U};
+ idt_flags flags{idt_flags::DESCRIPTOR_LEVEL_KERNEL};
+ gate_descriptor gate_descriptor{selector, ist, flags, offset};
+ return interrupt_descriptor_table{gate_descriptor};
}
} // namespace
diff --git a/arch/x86_64/src/context_switching/main.cpp b/arch/x86_64/src/context_switching/main.cpp
index 95a25e0..c3c0cf0 100644
--- a/arch/x86_64/src/context_switching/main.cpp
+++ b/arch/x86_64/src/context_switching/main.cpp
@@ -13,7 +13,10 @@ namespace teachos::arch::context_switching
decltype(auto) global_descriptor_table = segment_descriptor_table::initialize_global_descriptor_table();
decltype(auto) interrupt_descriptor_table = interrupt_descriptor_table::initialize_interrupt_descriptor_table();
- kernel::cpu::jmp((uint64_t)&global_descriptor_table.at(1), boot::segment_register_reload_pointer);
+ interrupt_descriptor_table::segment_selector segment_selector{
+ 1U, interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_KERNEL};
+ kernel::cpu::far_pointer pointer{boot::segment_register_reload_pointer, segment_selector};
+ kernel::cpu::jmp(pointer);
// Load task state segment descriptor from the last element in the global descriptor table, done by calculating
// offset in bytes to the start of the segment descriptor (5 * 16) = 80
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<uint16_t>(segment)};
- asm volatile("jmp *%0" : : "m"(far_pointer));
+ asm volatile("jmp *%[input]" : /* no output from call */ : [input] "m"(pointer));
}
-
} // namespace teachos::arch::kernel::cpu