diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-03-20 21:48:30 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-03-20 21:48:30 +0100 |
| commit | dd2dc3ef9a5318a0f7c7c35be59759ab08adc3dc (patch) | |
| tree | 8b52da9f3d00165055262c852d3aabd545e4d70a /arch/x86_64/include | |
| parent | 96f1511dbe2e80223732bcbef8068c3d5a330cee (diff) | |
| download | teachos-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.hpp | 57 |
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 |
