aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/include
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-03-20 21:48:30 +0100
committerFelix Morgner <felix.morgner@ost.ch>2026-03-20 21:48:30 +0100
commitdd2dc3ef9a5318a0f7c7c35be59759ab08adc3dc (patch)
tree8b52da9f3d00165055262c852d3aabd545e4d70a /arch/x86_64/include
parent96f1511dbe2e80223732bcbef8068c3d5a330cee (diff)
downloadteachos-dd2dc3ef9a5318a0f7c7c35be59759ab08adc3dc.tar.xz
teachos-dd2dc3ef9a5318a0f7c7c35be59759ab08adc3dc.zip
x86_64/cpu: implement basic interrupt handling
Diffstat (limited to 'arch/x86_64/include')
-rw-r--r--arch/x86_64/include/arch/cpu/interrupts.hpp57
1 files changed, 55 insertions, 2 deletions
diff --git a/arch/x86_64/include/arch/cpu/interrupts.hpp b/arch/x86_64/include/arch/cpu/interrupts.hpp
index 92c5824..19358ac 100644
--- a/arch/x86_64/include/arch/cpu/interrupts.hpp
+++ b/arch/x86_64/include/arch/cpu/interrupts.hpp
@@ -30,7 +30,7 @@ namespace arch::cpu
//! Reserved
std::uint8_t : 5;
//! The type of this gate.
- gate_type gate_type : 4;
+ enum gate_type gate_type : 4;
//! Reserved
std::uint8_t : 1;
//! The privilege level required to enter through this gate.
@@ -48,14 +48,67 @@ namespace arch::cpu
static_assert(sizeof(gate_descriptor) == 2 * sizeof(std::uint64_t));
static_assert(std::is_aggregate_v<gate_descriptor>);
+ //! The stack frame as established by the low-level assembly interrupt stubs.
+ //!
+ //! @note The layout of this struct is reverse than what would reasonably be expected. The reason for this reversal is
+ //! that fact that it represents a stack frame. Stack frames on x86_64 grow towards lower addresses, meaning the first
+ //! item on the stack is the last item in C++ memory layout order.
+ struct interrupt_frame
+ {
+ struct
+ {
+ std::uint64_t r15;
+ std::uint64_t r14;
+ std::uint64_t r13;
+ std::uint64_t r12;
+ std::uint64_t r11;
+ std::uint64_t r10;
+ std::uint64_t r9;
+ std::uint64_t r8;
+ std::uint64_t rdi;
+ std::uint64_t rsi;
+ std::uint64_t rbp;
+ std::uint64_t rdx;
+ std::uint64_t rcx;
+ std::uint64_t rbx;
+ std::uint64_t rax;
+ } handler_saved;
+
+ struct
+ {
+ std::uint64_t number;
+ std::uint64_t error_code;
+ } interrupt;
+
+ struct
+ {
+ std::uint64_t rip;
+ std::uint64_t cs;
+ std::uint64_t rflags;
+ std::uint64_t rsp;
+ std::uint64_t ss;
+ } cpu_saved;
+ };
+
struct interrupt_descriptor_table
{
- interrupt_descriptor_table();
+ interrupt_descriptor_table() noexcept;
+
+ auto load() const -> void;
private:
std::array<gate_descriptor, 256> m_descriptors{};
};
+ struct [[gnu::packed]] interrupt_descriptor_table_register
+ {
+ std::uint16_t limit;
+ gate_descriptor const * base;
+
+ auto load() const -> void;
+ auto static read() -> interrupt_descriptor_table_register;
+ };
+
} // namespace arch::cpu
#endif \ No newline at end of file