#![no_std]
pub mod vmx;
use moon_struct::{cpuid::CPUID, inner::KDESCRIPTOR};
#[macro_export]
macro_rules! debugbreak {
() => {
unsafe {
core::arch::asm!("int 3");
}
};
}
use core::{arch::asm, ffi::c_void};
pub fn sidt(idt_info: *mut c_void) {
unsafe {
asm!(
"sidt [rcx]",
in("rcx") idt_info,
options(nostack),
);
}
}
pub fn segment_limit(selector: u64) -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"lsl rax, rcx",
out("rax") result,
in("rcx") selector,
options(nostack)
);
}
result
}
pub fn write_xcr0(value: u64) {
let low = value as u32;
let high = (value >> 32) as u32;
unsafe {
asm!(
"xsetbv",
in("ecx") 0,
in("eax") low,
in("edx") high,
options(nostack)
);
}
}
pub fn read_msr(msr: u32) -> u64 {
let mut low: u32;
let mut high: u32;
unsafe {
asm!(
"rdmsr",
in("ecx") msr,
out("eax") low,
out("edx") high,
options(nostack)
);
}
((high as u64) << 32) | (low as u64)
}
pub fn write_msr(msr: u32, value: u64) {
let low = value as u32;
let high = (value >> 32) as u32;
unsafe {
asm!(
"wrmsr",
in("ecx") msr,
in("eax") low,
in("edx") high,
options(nostack)
);
}
}
pub fn read_cr0() -> u64 {
let mut result: u64;
unsafe {
asm!(
"mov rax,cr0",
out("rax") result,
options(nostack)
);
}
result
}
pub fn write_cr0(value: u64) {
unsafe {
asm!(
"mov cr0,rcx",
in("rcx") value,
options(nostack)
);
}
}
pub fn read_cr3() -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"mov rax,cr3",
out("rax") result,
options(nostack)
);
}
result
}
pub fn write_cr3(value: u64) {
unsafe {
asm!(
"mov cr3,rcx",
in("rcx") value,
options(nostack)
);
}
}
pub fn read_cr4() -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"mov rax,cr4",
out("rax") result,
options(nostack)
);
}
result
}
pub fn write_cr4(value: u64) {
unsafe {
asm!(
"mov cr4,rcx",
in("rcx") value,
options(nostack)
);
}
}
pub fn read_cr8() -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"mov rax,cr8",
out("rax") result,
options(nostack)
);
}
result
}
pub fn write_cr8(value: u64) {
unsafe {
asm!(
"mov cr8,rcx",
in("rcx") value,
options(nostack)
);
}
}
pub fn lgdt(addr: &KDESCRIPTOR) {
unsafe {
asm!(
"lgdt [rax+6]",
in("rax") addr,
options(nostack),
);
}
}
pub fn lidt(addr: &KDESCRIPTOR) {
unsafe {
asm!(
"lidt [rax+6]",
in("rax") addr,
options(nostack),
);
}
}
pub fn stosq(destination: *mut u64, value: u64, count: u64) {
unsafe {
asm!(
"rep stosq",
inout("rdi") destination => _,
in("rax") value,
inout("rcx") count => _,
options(nostack),
);
}
}
pub fn bit_scan_forward64(index: *mut u32, mask: u64) {
let _val: u64;
unsafe {
asm!(
"bsf rax,rax",
"mov [rcx],eax",
inout("rax") mask => _val,
in("rcx") index,
options(nostack),
);
}
}
pub fn cpuidex(eax: u32, ecx: u32) -> CPUID {
let mut result = CPUID::default();
let r_eax: u32;
let r_ebx: u32;
let r_ecx: u32;
let r_edx: u32;
unsafe {
asm!(
"push rbx",
"cpuid",
"mov r8d, ebx",
"pop rbx",
inout("eax") eax => r_eax,
inout("ecx") ecx => r_ecx,
lateout("edx") r_edx,
lateout("r8") r_ebx,
);
}
result.eax = r_eax;
result.ebx = r_ebx;
result.ecx = r_ecx;
result.edx = r_edx;
result
}
pub fn read_cs() -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"mov rax,cs",
out("rax") result,
options(nostack)
);
}
result
}
pub fn read_ds() -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"mov rax,ds",
out("rax") result,
options(nostack)
);
}
result
}
pub fn read_es() -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"mov rax,es",
out("rax") result,
options(nostack)
);
}
result
}
pub fn read_ss() -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"mov rax,ss",
out("rax") result,
options(nostack)
);
}
result
}
pub fn read_fs() -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"mov rax,fs",
out("rax") result,
options(nostack)
);
}
result
}
pub fn read_gs() -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"mov rax,gs",
out("rax") result,
options(nostack)
);
}
result
}
pub fn read_gs_current_thread() -> u64 {
let mut result: u64;
unsafe {
asm!(
"xor rax,rax",
"mov rax,gs:0x188",
out("rax") result,
options(nostack)
);
}
result
}
pub fn write_rflags(value: u64) {
unsafe {
asm!(
"push rcx",
"popfq",
in("rcx") value,
);
}
}
pub fn read_rflags() -> u64 {
let mut result: u64;
unsafe {
asm!(
"pushfq",
"pop rax",
out("rax") result,
);
}
result
}