curiOS/kernel/src/x86_64/instructions.rs
2026-07-23 19:18:03 +02:00

110 lines
2.6 KiB
Rust

#[inline]
pub fn hlt() {
unsafe {
core::arch::asm!("hlt", options(nomem, nostack, preserves_flags));
}
}
#[inline]
pub unsafe fn lidt(idt: &super::idt::IdtRegister) {
unsafe {
core::arch::asm!(
"lidt [{}]",
in(reg) idt,
options(readonly, nostack, preserves_flags)
);
}
}
#[inline]
pub fn int3() {
unsafe {
core::arch::asm!("int3", options(nomem, nostack, preserves_flags));
}
}
macro_rules! read_segment {
($segment:literal) => {
{
let value: u16;
unsafe {
core::arch::asm!(
concat!("mov {0:x}, ", $segment),
out(reg) value,
options(nomem, nostack, preserves_flags)
);
}
value
}
}
}
#[inline]
pub unsafe fn get_cs() -> u16 {
read_segment!("cs")
}
pub mod msr {
use core::arch::asm;
pub const MSR_STAR: u32 = 0xC000_0081;
pub const MSR_LSTAR: u32 = 0xC000_0082;
pub const MSR_CSTAR: u32 = 0xC000_0083;
pub const MSR_SFMASK: u32 = 0xC000_0084;
pub const MSR_FS_BASE: u32 = 0xC000_0100;
pub const MSR_GS_BASE: u32 = 0xC000_0101;
pub const MSR_KERNEL_GS_BASE: u32 = 0xC000_0102;
/// Reads the value of the specified Model-Specific Register (MSR).
/// # Safety
/// This operation is inherently unsafe.
#[inline]
pub unsafe fn read_msr(msr: u32) -> u64 {
unsafe {
let eax: u32;
let edx: u32;
asm!(
"rdmsr",
in("ecx") msr,
out("eax") eax,
out("edx") edx,
options(nomem, nostack, preserves_flags)
);
((edx as u64) << 32) | (eax as u64)
}
}
/// Writes the value to the specified Model-Specific Register (MSR).
/// # Safety
/// This operation is inherently unsafe.
#[inline]
pub unsafe fn write_msr(msr: u32, value: u64) {
unsafe {
let eax = value as u32;
let edx = (value >> 32) as u32;
asm!(
"wrmsr",
in("ecx") msr,
in("eax") eax,
in("edx") edx,
options(nomem, nostack, preserves_flags)
);
}
}
}
#[inline]
pub fn rdtsc() -> u64 {
let low: u32;
let high: u32;
unsafe {
core::arch::asm!(
"rdtsc",
out("eax") low,
out("edx") high,
options(nomem, nostack, preserves_flags)
);
}
((high as u64) << 32) | (low as u64)
}