use core::arch::global_asm;
use x86_64::{
VirtAddr,
registers::{
model_specific::{Efer, EferFlags, LStar, SFMask},
rflags::RFlags,
},
};
use super::RawUserContext;
use crate::mm::PagingConstsTrait;
global_asm!(
include_str!("syscall.S"),
USER_CS = const super::gdt::USER_CS.0,
USER_SS = const super::gdt::USER_SS.0,
ADDRESS_WIDTH = const crate::arch::mm::PagingConsts::ADDRESS_WIDTH,
);
pub(super) unsafe fn init_on_cpu() {
const RFLAGS_MASK: u64 = 0x47700;
unsafe {
LStar::write(VirtAddr::new(syscall_entry as *const () as usize as u64));
SFMask::write(RFlags::from_bits(RFLAGS_MASK).unwrap());
Efer::update(|efer| {
efer.insert(EferFlags::SYSTEM_CALL_EXTENSIONS);
});
}
}
unsafe extern "C" {
unsafe fn syscall_entry();
unsafe fn syscall_return(regs: &mut RawUserContext);
}
impl RawUserContext {
pub(in crate::arch) fn run(&mut self) {
crate::arch::irq::disable_local();
unsafe {
syscall_return(self);
}
}
}