:github_url: https://github.com/nyx-org/gaia .. _program_listing_file_platform_amd64_idt.hpp: Program Listing for File idt.hpp ================================ |exhale_lsh| :ref:`Return to documentation for file ` (``platform/amd64/idt.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include struct [[gnu::packed]] Gaia::Hal::InterruptFrame { uint64_t r15; uint64_t r14; uint64_t r13; uint64_t r12; uint64_t r11; uint64_t r10; uint64_t r9; uint64_t r8; uint64_t rbp; uint64_t rdi; uint64_t rsi; uint64_t rdx; uint64_t rcx; uint64_t rbx; uint64_t rax; uint64_t intno; uint64_t err; uint64_t rip; uint64_t cs; uint64_t rflags; uint64_t rsp; uint64_t ss; }; struct Gaia::Hal::InterruptEntry { Ipl ipl; InterruptHandler *handler; void *arg; ListNode link; }; struct [[gnu::packed]] GsCpuInfo { uintptr_t syscall_kernel_stack; uintptr_t syscall_user_stack; }; struct [[gnu::packed]] Gaia::Hal::CpuContext { GsCpuInfo info; void *gs_base; void *fs_base; InterruptFrame regs = {}; void *fpu_regs = nullptr; bool user = true; void load(InterruptFrame *regs) { if (user) { Amd64::simd_restore_state(fpu_regs); } // Amd64::set_gs_base(&info); if (user && gs_base != nullptr) { Amd64::set_kernel_gs_base(gs_base); } else if (!user) Amd64::set_kernel_gs_base(&info); Amd64::set_fs_base(fs_base); memcpy(regs, &this->regs, sizeof(this->regs)); } void save(InterruptFrame *regs) { if (user) Amd64::simd_save_state(fpu_regs); ASSERT(regs != nullptr); this->gs_base = Amd64::get_kernel_gs_base(); this->fs_base = Amd64::get_fs_base(); this->regs = *regs; } CpuContext() : user(false) {} CpuContext(uintptr_t rip, uintptr_t kstack, uintptr_t ustack, bool user) : user(user) { if (user) { fpu_regs = (void *)Hal::phys_to_virt( (uintptr_t)::Gaia::Vm::phys_alloc(true).unwrap()); Amd64::simd_init_context(fpu_regs); } regs = {}; regs.rsp = user ? ustack : kstack; regs.rip = rip; info.syscall_kernel_stack = kstack; info.syscall_user_stack = ustack; regs.rflags = 0x202; regs.ss = user ? 0x3b : 0x30; regs.cs = user ? 0x43 : 0x28; gs_base = user ? nullptr : &info; fs_base = nullptr; } }; namespace Gaia::Amd64 { void idt_init(); }