Program Listing for File idt.hpp¶
↰ Return to documentation for file (platform/amd64/idt.hpp
)
/* SPDX-License-Identifier: BSD-2-Clause */
#pragma once
#include <amd64/asm.hpp>
#include <amd64/simd.hpp>
#include <hal/hal.hpp>
#include <hal/int.hpp>
#include <vm/phys.hpp>
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<InterruptEntry> 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();
}