From a143355627240bd58f97c4a881b79e86b3ea07cc Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Fri, 25 Feb 2022 13:06:42 +0100 Subject: [PATCH] Remove external assembly (#343) --- Cargo.toml | 11 +- build.rs | 54 ----- src/asm/asm.s | 352 ------------------------------- src/asm/mod.rs | 314 --------------------------- src/instructions/interrupts.rs | 22 -- src/instructions/mod.rs | 18 -- src/instructions/port.rs | 58 +---- src/instructions/segmentation.rs | 35 --- src/instructions/tables.rs | 27 --- src/instructions/tlb.rs | 11 - src/lib.rs | 4 - src/registers/control.rs | 39 ---- src/registers/mod.rs | 2 +- src/registers/model_specific.rs | 31 +-- src/registers/mxcsr.rs | 19 +- src/registers/rflags.rs | 12 -- src/registers/xcontrol.rs | 13 -- 17 files changed, 26 insertions(+), 996 deletions(-) delete mode 100644 build.rs delete mode 100644 src/asm/asm.s delete mode 100644 src/asm/mod.rs diff --git a/Cargo.toml b/Cargo.toml index ffec90e41..187dc6e95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,19 +30,18 @@ bit_field = "0.10.1" bitflags = "1.0.4" volatile = "0.4.4" -[build-dependencies] -cc = { version = "1.0.37", optional = true } - [features] default = [ "nightly", "instructions" ] instructions = [] -external_asm = [ "cc" ] -nightly = [ "inline_asm", "const_fn", "abi_x86_interrupt", "doc_cfg" ] -inline_asm = [] +nightly = [ "const_fn", "abi_x86_interrupt", "doc_cfg" ] abi_x86_interrupt = [] const_fn = [] doc_cfg = [] +# These features are no longer used and only there for backwards compatibility. +external_asm = [] +inline_asm = [] + [package.metadata.release] no-dev-version = true pre-release-replacements = [ diff --git a/build.rs b/build.rs deleted file mode 100644 index 21c783bad..000000000 --- a/build.rs +++ /dev/null @@ -1,54 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - - #[cfg(all(feature = "external_asm", windows))] - compile_error!("\"external_asm\" feature is not available on windows toolchain!"); - - #[cfg(feature = "instructions")] - if std::env::var("CARGO_CFG_TARGET_ARCH").unwrap() != "x86_64" { - panic!("\"instructions\" feature is only available for x86_64 targets!"); - } - - #[cfg(all( - feature = "instructions", - not(feature = "inline_asm"), - not(feature = "external_asm") - ))] - compile_error!("\"instructions\" feature is enabled, but neither feature \"external_asm\" nor \"inline_asm\" was set!"); - - #[cfg(all(feature = "inline_asm", feature = "external_asm"))] - compile_error!( - "\"inline_asm\" and \"external_asm\" features can not be enabled at the same time!" - ); - - #[cfg(all(feature = "instructions", feature = "external_asm"))] - { - use std::ffi::OsString; - use std::fs; - - let entries = fs::read_dir("src/asm") - .unwrap() - .filter_map(|f| { - f.ok().and_then(|e| { - let path = e.path(); - match path.extension() { - Some(ext) if ext.eq(&OsString::from("s")) => Some(path), - _ => None, - } - }) - }) - .collect::>(); - - cc::Build::new() - .no_default_flags(true) - .files(&entries) - .pic(true) - .static_flag(true) - .shared_flag(false) - .compile("x86_64_asm"); - - for e in entries { - println!("cargo:rerun-if-changed={}", e.to_str().unwrap()); - } - } -} diff --git a/src/asm/asm.s b/src/asm/asm.s deleted file mode 100644 index 831828a82..000000000 --- a/src/asm/asm.s +++ /dev/null @@ -1,352 +0,0 @@ -.text -.code64 - -# REMEMBER: This code uses the AMD64 calling convention: -# Arguments: RDI, RSI, RDX, RCX -# Return: RAX - -.global _x86_64_asm_interrupt_enable -.p2align 4 -_x86_64_asm_interrupt_enable: - sti - retq - -.global _x86_64_asm_interrupt_disable -.p2align 4 -_x86_64_asm_interrupt_disable: - cli - retq - -.global _x86_64_asm_interrupt_enable_and_hlt -.p2align 4 -_x86_64_asm_interrupt_enable_and_hlt: - sti - hlt - retq - -.global _x86_64_asm_int3 -.p2align 4 -_x86_64_asm_int3: - int3 - retq - -.global _x86_64_asm_read_from_port_u8 -.p2align 4 -_x86_64_asm_read_from_port_u8: - mov %edi, %edx - inb (%dx), %al - retq - -.global _x86_64_asm_read_from_port_u16 -.p2align 4 -_x86_64_asm_read_from_port_u16: - mov %edi, %edx - inw (%dx), %ax - retq - -.global _x86_64_asm_read_from_port_u32 -.p2align 4 -_x86_64_asm_read_from_port_u32: - mov %edi, %edx - inl (%dx), %eax - retq - - -.global _x86_64_asm_write_to_port_u8 -.p2align 4 -_x86_64_asm_write_to_port_u8: - mov %edi, %edx - mov %si, %ax - outb %al, (%dx) - retq - -.global _x86_64_asm_write_to_port_u16 -.p2align 4 -_x86_64_asm_write_to_port_u16: - mov %edi, %edx - mov %si, %ax - outw %ax, (%dx) - retq - -.global _x86_64_asm_write_to_port_u32 -.p2align 4 -_x86_64_asm_write_to_port_u32: - mov %edi, %edx - mov %esi, %eax - outl %eax, (%dx) - retq - -.global _x86_64_asm_set_cs -.p2align 4 -_x86_64_asm_set_cs: - pushq %rdi - leaq 1f(%rip), %rax - pushq %rax - lretq -1: - retq - -.global _x86_64_asm_get_cs -.p2align 4 -_x86_64_asm_get_cs: - mov %cs, %ax - retq - -.global _x86_64_asm_invlpg -.p2align 4 -_x86_64_asm_invlpg: - invlpg (%rdi) - retq - -.global _x86_64_asm_invpcid -.p2align 4 -_x86_64_asm_invpcid: - invpcid (%rsi), %rdi - retq - -.global _x86_64_asm_ltr -.p2align 4 -_x86_64_asm_ltr: - mov %edi, %edx - ltr %dx - retq - -.global _x86_64_asm_lgdt -.p2align 4 -_x86_64_asm_lgdt: - lgdt (%rdi) - retq - -.global _x86_64_asm_lidt -.p2align 4 -_x86_64_asm_lidt: - lidt (%rdi) - retq - -.global _x86_64_asm_sgdt -.p2align 4 -_x86_64_asm_sgdt: - sgdt (%rdi) - retq - -.global _x86_64_asm_sidt -.p2align 4 -_x86_64_asm_sidt: - sidt (%rdi) - retq - -.global _x86_64_asm_write_rflags -.p2align 4 -_x86_64_asm_write_rflags: - pushq %rdi - popfq - retq - -.global _x86_64_asm_read_rflags -.p2align 4 -_x86_64_asm_read_rflags: - pushfq - popq %rax - retq - -.global _x86_64_asm_load_ss -.p2align 4 -_x86_64_asm_load_ss: - mov %di, %ss - retq - -.global _x86_64_asm_load_ds -.p2align 4 -_x86_64_asm_load_ds: - mov %di, %ds - retq - -.global _x86_64_asm_load_es -.p2align 4 -_x86_64_asm_load_es: - mov %di, %es - retq - -.global _x86_64_asm_load_fs -.p2align 4 -_x86_64_asm_load_fs: - mov %di, %fs - retq - -.global _x86_64_asm_load_gs -.p2align 4 -_x86_64_asm_load_gs: - mov %di, %gs - retq - -.global _x86_64_asm_get_ss -.p2align 4 -_x86_64_asm_get_ss: - mov %ss, %ax - retq - -.global _x86_64_asm_get_ds -.p2align 4 -_x86_64_asm_get_ds: - mov %ds, %ax - retq - -.global _x86_64_asm_get_es -.p2align 4 -_x86_64_asm_get_es: - mov %es, %ax - retq - -.global _x86_64_asm_get_fs -.p2align 4 -_x86_64_asm_get_fs: - mov %fs, %ax - retq - -.global _x86_64_asm_get_gs -.p2align 4 -_x86_64_asm_get_gs: - mov %gs, %ax - retq - -.global _x86_64_asm_swapgs -.p2align 4 -_x86_64_asm_swapgs: - swapgs - retq - -.global _x86_64_asm_read_cr0 -.p2align 4 -_x86_64_asm_read_cr0: - movq %cr0, %rax - retq - -.global _x86_64_asm_read_cr2 -.p2align 4 -_x86_64_asm_read_cr2: - movq %cr2, %rax - retq - -.global _x86_64_asm_read_cr3 -.p2align 4 -_x86_64_asm_read_cr3: - movq %cr3, %rax - retq - -.global _x86_64_asm_read_cr4 -.p2align 4 -_x86_64_asm_read_cr4: - movq %cr4, %rax - retq - -.global _x86_64_asm_write_cr0 -.p2align 4 -_x86_64_asm_write_cr0: - movq %rdi, %cr0 - retq - -.global _x86_64_asm_write_cr3 -.p2align 4 -_x86_64_asm_write_cr3: - movq %rdi, %cr3 - retq - -.global _x86_64_asm_write_cr4 -.p2align 4 -_x86_64_asm_write_cr4: - movq %rdi, %cr4 - retq - -.global _x86_64_asm_rdmsr -.p2align 4 -_x86_64_asm_rdmsr: - mov %edi, %ecx # First param is the MSR number - rdmsr - shl $32, %rdx # shift edx to upper 32bit - mov %eax, %eax # clear upper 32bit of rax - or %rdx, %rax # or with rdx - retq - -.global _x86_64_asm_wrmsr -.p2align 4 -_x86_64_asm_wrmsr: - movl %edi, %ecx # First param is the MSR number - movl %esi, %eax # Second param is the low 32-bits - wrmsr # Third param (high 32-bits) is already in %edx - retq - -.global _x86_64_asm_hlt -.p2align 4 -_x86_64_asm_hlt: - hlt - retq - -.global _x86_64_asm_nop -.p2align 4 -_x86_64_asm_nop: - nop - retq - -.global _x86_64_asm_bochs -.p2align 4 -_x86_64_asm_bochs: - xchgw %bx, %bx - retq - -.global _x86_64_asm_rdfsbase -.p2align 4 -_x86_64_asm_rdfsbase: - rdfsbase %rax - retq - -.global _x86_64_asm_wrfsbase -.p2align 4 -_x86_64_asm_wrfsbase: - wrfsbase %rdi - retq - -.global _x86_64_asm_rdgsbase -.p2align 4 -_x86_64_asm_rdgsbase: - rdgsbase %rax - retq - -.global _x86_64_asm_wrgsbase -.p2align 4 -_x86_64_asm_wrgsbase: - wrgsbase %rdi - retq - -.global _x86_64_asm_xgetbv -.p2align 4 -_x86_64_asm_xgetbv: - mov %edi, %ecx # First param is the XCR number - xgetbv - shl $32, %rdx # shift edx to upper 32bit - mov %eax, %eax # clear upper 32bit of rax - or %rdx, %rax # or with rdx - retq - -.global _x86_64_asm_xsetbv -.p2align 4 -_x86_64_asm_xsetbv: - movl %edi, %ecx # First param is the XCR number - movl %esi, %eax # Second param is the low 32-bits - xsetbv # Third param (high 32-bits) is already in %edx - retq - -.global _x86_64_asm_write_mxcsr -.p2align 4 -_x86_64_asm_write_mxcsr: - pushq %rdi - ldmxcsr (%rsp) - popq %rdi - retq - -.global _x86_64_asm_read_mxcsr -.p2align 4 -_x86_64_asm_read_mxcsr: - pushq $0 - stmxcsr (%rsp) - popq %rax - retq diff --git a/src/asm/mod.rs b/src/asm/mod.rs deleted file mode 100644 index 6d481dad9..000000000 --- a/src/asm/mod.rs +++ /dev/null @@ -1,314 +0,0 @@ -#[link(name = "x86_64_asm", kind = "static")] -extern "sysv64" { - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_interrupt_enable" - )] - pub(crate) fn x86_64_asm_interrupt_enable(); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_interrupt_disable" - )] - pub(crate) fn x86_64_asm_interrupt_disable(); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_interrupt_enable_and_hlt" - )] - pub(crate) fn x86_64_asm_interrupt_enable_and_hlt(); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_int3" - )] - pub(crate) fn x86_64_asm_int3(); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_hlt" - )] - pub(crate) fn x86_64_asm_hlt(); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_nop" - )] - pub(crate) fn x86_64_asm_nop(); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_bochs" - )] - pub(crate) fn x86_64_asm_bochs(); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_read_from_port_u8" - )] - pub(crate) fn x86_64_asm_read_from_port_u8(port: u16) -> u8; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_read_from_port_u16" - )] - pub(crate) fn x86_64_asm_read_from_port_u16(port: u16) -> u16; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_read_from_port_u32" - )] - pub(crate) fn x86_64_asm_read_from_port_u32(port: u16) -> u32; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_write_to_port_u8" - )] - pub(crate) fn x86_64_asm_write_to_port_u8(port: u16, value: u8); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_write_to_port_u16" - )] - pub(crate) fn x86_64_asm_write_to_port_u16(port: u16, value: u16); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_write_to_port_u32" - )] - pub(crate) fn x86_64_asm_write_to_port_u32(port: u16, value: u32); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_set_cs" - )] - pub(crate) fn x86_64_asm_set_cs(sel: u64); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_load_ss" - )] - pub(crate) fn x86_64_asm_load_ss(sel: u16); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_load_ds" - )] - pub(crate) fn x86_64_asm_load_ds(sel: u16); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_load_es" - )] - pub(crate) fn x86_64_asm_load_es(sel: u16); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_load_fs" - )] - pub(crate) fn x86_64_asm_load_fs(sel: u16); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_load_gs" - )] - pub(crate) fn x86_64_asm_load_gs(sel: u16); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_get_ss" - )] - pub(crate) fn x86_64_asm_get_ss() -> u16; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_get_ds" - )] - pub(crate) fn x86_64_asm_get_ds() -> u16; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_get_es" - )] - pub(crate) fn x86_64_asm_get_es() -> u16; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_get_fs" - )] - pub(crate) fn x86_64_asm_get_fs() -> u16; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_get_gs" - )] - pub(crate) fn x86_64_asm_get_gs() -> u16; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_swapgs" - )] - pub(crate) fn x86_64_asm_swapgs(); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_get_cs" - )] - pub(crate) fn x86_64_asm_get_cs() -> u16; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_lgdt" - )] - pub(crate) fn x86_64_asm_lgdt(gdt: *const crate::instructions::tables::DescriptorTablePointer); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_lidt" - )] - pub(crate) fn x86_64_asm_lidt(idt: *const crate::instructions::tables::DescriptorTablePointer); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_sgdt" - )] - pub(crate) fn x86_64_asm_sgdt(gdt: *mut crate::instructions::tables::DescriptorTablePointer); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_sidt" - )] - pub(crate) fn x86_64_asm_sidt(idt: *mut crate::instructions::tables::DescriptorTablePointer); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_ltr" - )] - pub(crate) fn x86_64_asm_ltr(sel: u16); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_invlpg" - )] - pub(crate) fn x86_64_asm_invlpg(addr: u64); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_invpcid" - )] - pub(crate) fn x86_64_asm_invpcid(kind: u64, desc: u64); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_read_cr0" - )] - pub(crate) fn x86_64_asm_read_cr0() -> u64; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_write_cr0" - )] - pub(crate) fn x86_64_asm_write_cr0(value: u64); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_read_cr2" - )] - pub(crate) fn x86_64_asm_read_cr2() -> u64; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_read_cr3" - )] - pub(crate) fn x86_64_asm_read_cr3() -> u64; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_write_cr3" - )] - pub(crate) fn x86_64_asm_write_cr3(value: u64); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_read_cr4" - )] - pub(crate) fn x86_64_asm_read_cr4() -> u64; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_write_cr4" - )] - pub(crate) fn x86_64_asm_write_cr4(value: u64); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_rdmsr" - )] - pub(crate) fn x86_64_asm_rdmsr(msr: u32) -> u64; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_wrmsr" - )] - pub(crate) fn x86_64_asm_wrmsr(msr: u32, low: u32, high: u32); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_read_rflags" - )] - pub(crate) fn x86_64_asm_read_rflags() -> u64; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_write_rflags" - )] - pub(crate) fn x86_64_asm_write_rflags(val: u64); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_rdfsbase" - )] - pub(crate) fn x86_64_asm_rdfsbase() -> u64; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_wrfsbase" - )] - pub(crate) fn x86_64_asm_wrfsbase(val: u64); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_rdgsbase" - )] - pub(crate) fn x86_64_asm_rdgsbase() -> u64; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_wrgsbase" - )] - pub(crate) fn x86_64_asm_wrgsbase(val: u64); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_xgetbv" - )] - pub(crate) fn x86_64_asm_xgetbv(xcr: u32) -> u64; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_xsetbv" - )] - pub(crate) fn x86_64_asm_xsetbv(xcr: u32, low: u32, high: u32); - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_read_mxcsr" - )] - pub(crate) fn x86_64_asm_read_mxcsr() -> u32; - - #[cfg_attr( - any(target_env = "gnu", target_env = "musl"), - link_name = "_x86_64_asm_write_mxcsr" - )] - pub(crate) fn x86_64_asm_write_mxcsr(val: u32); -} diff --git a/src/instructions/interrupts.rs b/src/instructions/interrupts.rs index d850cf0f3..6f0cd8381 100644 --- a/src/instructions/interrupts.rs +++ b/src/instructions/interrupts.rs @@ -1,6 +1,5 @@ //! Enabling and disabling interrupts -#[cfg(feature = "inline_asm")] use core::arch::asm; /// Returns whether interrupts are enabled. @@ -17,11 +16,7 @@ pub fn are_enabled() -> bool { #[inline] pub fn enable() { unsafe { - #[cfg(feature = "inline_asm")] asm!("sti", options(nomem, nostack)); - - #[cfg(not(feature = "inline_asm"))] - crate::asm::x86_64_asm_interrupt_enable(); } } @@ -31,11 +26,7 @@ pub fn enable() { #[inline] pub fn disable() { unsafe { - #[cfg(feature = "inline_asm")] asm!("cli", options(nomem, nostack)); - - #[cfg(not(feature = "inline_asm"))] - crate::asm::x86_64_asm_interrupt_disable(); } } @@ -130,11 +121,7 @@ where #[inline] pub fn enable_and_hlt() { unsafe { - #[cfg(feature = "inline_asm")] asm!("sti; hlt", options(nomem, nostack)); - - #[cfg(not(feature = "inline_asm"))] - crate::asm::x86_64_asm_interrupt_enable_and_hlt(); } } @@ -142,11 +129,7 @@ pub fn enable_and_hlt() { #[inline] pub fn int3() { unsafe { - #[cfg(feature = "inline_asm")] asm!("int3", options(nomem, nostack)); - - #[cfg(not(feature = "inline_asm"))] - crate::asm::x86_64_asm_int3(); } } @@ -155,11 +138,6 @@ pub fn int3() { /// This currently needs to be a macro because the `int` argument needs to be an /// immediate. This macro will be replaced by a generic function when support for /// const generics is implemented in Rust. -#[cfg(feature = "inline_asm")] -#[cfg_attr( - feature = "doc_cfg", - doc(cfg(any(feature = "nightly", feature = "inline_asm"))) -)] #[macro_export] macro_rules! software_interrupt { ($x:expr) => {{ diff --git a/src/instructions/mod.rs b/src/instructions/mod.rs index bd35f2a82..984c13284 100644 --- a/src/instructions/mod.rs +++ b/src/instructions/mod.rs @@ -9,18 +9,13 @@ pub mod segmentation; pub mod tables; pub mod tlb; -#[cfg(feature = "inline_asm")] use core::arch::asm; /// Halts the CPU until the next interrupt arrives. #[inline] pub fn hlt() { unsafe { - #[cfg(feature = "inline_asm")] asm!("hlt", options(nomem, nostack, preserves_flags)); - - #[cfg(not(feature = "inline_asm"))] - crate::asm::x86_64_asm_hlt(); } } @@ -33,11 +28,7 @@ pub fn hlt() { #[inline] pub fn nop() { unsafe { - #[cfg(feature = "inline_asm")] asm!("nop", options(nomem, nostack, preserves_flags)); - - #[cfg(not(feature = "inline_asm"))] - crate::asm::x86_64_asm_nop(); } } @@ -46,21 +37,12 @@ pub fn nop() { #[inline] pub fn bochs_breakpoint() { unsafe { - #[cfg(feature = "inline_asm")] asm!("xchg bx, bx", options(nomem, nostack, preserves_flags)); - - #[cfg(not(feature = "inline_asm"))] - crate::asm::x86_64_asm_bochs(); } } /// Gets the current instruction pointer. Note that this is only approximate as it requires a few /// instructions to execute. -#[cfg(feature = "inline_asm")] -#[cfg_attr( - feature = "doc_cfg", - doc(cfg(any(feature = "nightly", feature = "inline_asm"))) -)] #[inline(always)] pub fn read_rip() -> crate::VirtAddr { let rip: u64; diff --git a/src/instructions/port.rs b/src/instructions/port.rs index b23be4401..0263d0e0e 100644 --- a/src/instructions/port.rs +++ b/src/instructions/port.rs @@ -1,6 +1,5 @@ //! Access to I/O ports -#[cfg(feature = "inline_asm")] use core::arch::asm; use core::fmt; use core::marker::PhantomData; @@ -10,99 +9,60 @@ pub use crate::structures::port::{PortRead, PortWrite}; impl PortRead for u8 { #[inline] unsafe fn read_from_port(port: u16) -> u8 { - #[cfg(feature = "inline_asm")] - { - let value: u8; - unsafe { - asm!("in al, dx", out("al") value, in("dx") port, options(nomem, nostack, preserves_flags)); - } - value - } - #[cfg(not(feature = "inline_asm"))] + let value: u8; unsafe { - crate::asm::x86_64_asm_read_from_port_u8(port) + asm!("in al, dx", out("al") value, in("dx") port, options(nomem, nostack, preserves_flags)); } + value } } impl PortRead for u16 { #[inline] unsafe fn read_from_port(port: u16) -> u16 { - #[cfg(feature = "inline_asm")] - { - let value: u16; - unsafe { - asm!("in ax, dx", out("ax") value, in("dx") port, options(nomem, nostack, preserves_flags)); - } - value - } - #[cfg(not(feature = "inline_asm"))] + let value: u16; unsafe { - crate::asm::x86_64_asm_read_from_port_u16(port) + asm!("in ax, dx", out("ax") value, in("dx") port, options(nomem, nostack, preserves_flags)); } + value } } impl PortRead for u32 { #[inline] unsafe fn read_from_port(port: u16) -> u32 { - #[cfg(feature = "inline_asm")] - { - let value: u32; - unsafe { - asm!("in eax, dx", out("eax") value, in("dx") port, options(nomem, nostack, preserves_flags)); - } - value - } - #[cfg(not(feature = "inline_asm"))] + let value: u32; unsafe { - crate::asm::x86_64_asm_read_from_port_u32(port) + asm!("in eax, dx", out("eax") value, in("dx") port, options(nomem, nostack, preserves_flags)); } + value } } impl PortWrite for u8 { #[inline] unsafe fn write_to_port(port: u16, value: u8) { - #[cfg(feature = "inline_asm")] unsafe { asm!("out dx, al", in("dx") port, in("al") value, options(nomem, nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_write_to_port_u8(port, value); - } } } impl PortWrite for u16 { #[inline] unsafe fn write_to_port(port: u16, value: u16) { - #[cfg(feature = "inline_asm")] unsafe { asm!("out dx, ax", in("dx") port, in("ax") value, options(nomem, nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_write_to_port_u16(port, value); - } } } impl PortWrite for u32 { #[inline] unsafe fn write_to_port(port: u16, value: u32) { - #[cfg(feature = "inline_asm")] unsafe { asm!("out dx, eax", in("dx") port, in("eax") value, options(nomem, nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_write_to_port_u32(port, value); - } } } diff --git a/src/instructions/segmentation.rs b/src/instructions/segmentation.rs index fda49eec7..334c42237 100644 --- a/src/instructions/segmentation.rs +++ b/src/instructions/segmentation.rs @@ -6,21 +6,15 @@ use crate::{ structures::gdt::SegmentSelector, VirtAddr, }; -#[cfg(feature = "inline_asm")] use core::arch::asm; macro_rules! get_reg_impl { ($name:literal, $asm_get:ident) => { fn get_reg() -> SegmentSelector { let segment: u16; - #[cfg(feature = "inline_asm")] unsafe { asm!(concat!("mov {0:x}, ", $name), out(reg) segment, options(nomem, nostack, preserves_flags)); } - #[cfg(not(feature = "inline_asm"))] - unsafe { - segment = crate::asm::$asm_get(); - } SegmentSelector(segment) } }; @@ -32,15 +26,9 @@ macro_rules! segment_impl { get_reg_impl!($name, $asm_get); unsafe fn set_reg(sel: SegmentSelector) { - #[cfg(feature = "inline_asm")] unsafe { asm!(concat!("mov ", $name, ", {0:x}"), in(reg) sel.0, options(nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe{ - crate::asm::$asm_load(sel.0); - } } } }; @@ -51,28 +39,17 @@ macro_rules! segment64_impl { impl Segment64 for $type { const BASE: Msr = <$base>::MSR; fn read_base() -> VirtAddr { - #[cfg(feature = "inline_asm")] unsafe { let val: u64; asm!(concat!("rd", $name, "base {}"), out(reg) val, options(nomem, nostack, preserves_flags)); VirtAddr::new_unsafe(val) } - #[cfg(not(feature = "inline_asm"))] - unsafe { - VirtAddr::new_unsafe(crate::asm::$asm_rd()) - } } unsafe fn write_base(base: VirtAddr) { - #[cfg(feature = "inline_asm")] unsafe{ asm!(concat!("wr", $name, "base {}"), in(reg) base.as_u64(), options(nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe{ - crate::asm::$asm_wr(base.as_u64()); - } } } }; @@ -90,7 +67,6 @@ impl Segment for CS { /// would only be able to jump to 32-bit instruction pointers. Only Intel implements support /// for 64-bit far calls/jumps in long-mode, AMD does not. unsafe fn set_reg(sel: SegmentSelector) { - #[cfg(feature = "inline_asm")] unsafe { asm!( "push {sel}", @@ -103,11 +79,6 @@ impl Segment for CS { options(preserves_flags), ); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_set_cs(u64::from(sel.0)); - } } } @@ -127,15 +98,9 @@ impl GS { /// This function is unsafe because the caller must ensure that the /// swap operation cannot lead to undefined behavior. pub unsafe fn swap() { - #[cfg(feature = "inline_asm")] unsafe { asm!("swapgs", options(nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_swapgs(); - } } } diff --git a/src/instructions/tables.rs b/src/instructions/tables.rs index 28cb4faf5..5139df7ac 100644 --- a/src/instructions/tables.rs +++ b/src/instructions/tables.rs @@ -2,7 +2,6 @@ use crate::structures::gdt::SegmentSelector; use crate::VirtAddr; -#[cfg(feature = "inline_asm")] use core::arch::asm; pub use crate::structures::DescriptorTablePointer; @@ -20,15 +19,9 @@ pub use crate::structures::DescriptorTablePointer; /// GDT is safe. #[inline] pub unsafe fn lgdt(gdt: &DescriptorTablePointer) { - #[cfg(feature = "inline_asm")] unsafe { asm!("lgdt [{}]", in(reg) gdt, options(readonly, nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_lgdt(gdt as *const _); - } } /// Load an IDT. @@ -44,15 +37,9 @@ pub unsafe fn lgdt(gdt: &DescriptorTablePointer) { /// IDT is safe. #[inline] pub unsafe fn lidt(idt: &DescriptorTablePointer) { - #[cfg(feature = "inline_asm")] unsafe { asm!("lidt [{}]", in(reg) idt, options(readonly, nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_lidt(idt as *const _); - } } /// Get the address of the current GDT. @@ -63,11 +50,7 @@ pub fn sgdt() -> DescriptorTablePointer { base: VirtAddr::new(0), }; unsafe { - #[cfg(feature = "inline_asm")] asm!("sgdt [{}]", in(reg) &mut gdt, options(nostack, preserves_flags)); - - #[cfg(not(feature = "inline_asm"))] - crate::asm::x86_64_asm_sgdt(&mut gdt as *mut _); } gdt } @@ -80,11 +63,7 @@ pub fn sidt() -> DescriptorTablePointer { base: VirtAddr::new(0), }; unsafe { - #[cfg(feature = "inline_asm")] asm!("sidt [{}]", in(reg) &mut idt, options(nostack, preserves_flags)); - - #[cfg(not(feature = "inline_asm"))] - crate::asm::x86_64_asm_sidt(&mut idt as *mut _); } idt } @@ -98,13 +77,7 @@ pub fn sidt() -> DescriptorTablePointer { /// this TSS is safe. #[inline] pub unsafe fn load_tss(sel: SegmentSelector) { - #[cfg(feature = "inline_asm")] unsafe { asm!("ltr {0:x}", in(reg) sel.0, options(nomem, nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_ltr(sel.0); - } } diff --git a/src/instructions/tlb.rs b/src/instructions/tlb.rs index a45cf9f66..b300a2a74 100644 --- a/src/instructions/tlb.rs +++ b/src/instructions/tlb.rs @@ -1,18 +1,13 @@ //! Functions to flush the translation lookaside buffer (TLB). use crate::VirtAddr; -#[cfg(feature = "inline_asm")] use core::arch::asm; /// Invalidate the given address in the TLB using the `invlpg` instruction. #[inline] pub fn flush(addr: VirtAddr) { unsafe { - #[cfg(feature = "inline_asm")] asm!("invlpg [{}]", in(reg) addr.as_u64(), options(nostack, preserves_flags)); - - #[cfg(not(feature = "inline_asm"))] - crate::asm::x86_64_asm_invlpg(addr.as_u64()); } } @@ -98,13 +93,7 @@ pub unsafe fn flush_pcid(command: InvPicdCommand) { InvPicdCommand::AllExceptGlobal => kind = 3, } - #[cfg(feature = "inline_asm")] unsafe { asm!("invpcid {0}, [{1}]", in(reg) kind, in(reg) &desc, options(nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_invpcid(kind, &desc as *const _ as u64); - } } diff --git a/src/lib.rs b/src/lib.rs index ed086a522..cc47b745b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,6 @@ #![cfg_attr(feature = "const_fn", feature(const_mut_refs))] // GDT add_entry() #![cfg_attr(feature = "const_fn", feature(const_fn_fn_ptr_basics))] // IDT new() #![cfg_attr(feature = "const_fn", feature(const_fn_trait_bound))] // PageSize marker trait -#![cfg_attr(feature = "inline_asm", feature(asm))] #![cfg_attr(feature = "abi_x86_interrupt", feature(abi_x86_interrupt))] #![cfg_attr(feature = "doc_cfg", feature(doc_cfg))] #![warn(missing_docs)] @@ -45,9 +44,6 @@ macro_rules! const_fn { }; } -#[cfg(all(feature = "instructions", feature = "external_asm"))] -pub(crate) mod asm; - pub mod addr; pub mod instructions; pub mod registers; diff --git a/src/registers/control.rs b/src/registers/control.rs index bd2b06316..56fb987aa 100644 --- a/src/registers/control.rs +++ b/src/registers/control.rs @@ -161,7 +161,6 @@ bitflags! { mod x86_64 { use super::*; use crate::{instructions::tlb::Pcid, structures::paging::PhysFrame, PhysAddr, VirtAddr}; - #[cfg(feature = "inline_asm")] use core::arch::asm; impl Cr0 { @@ -176,14 +175,9 @@ mod x86_64 { pub fn read_raw() -> u64 { let value: u64; - #[cfg(feature = "inline_asm")] unsafe { asm!("mov {}, cr0", out(reg) value, options(nomem, nostack, preserves_flags)); } - #[cfg(not(feature = "inline_asm"))] - unsafe { - value = crate::asm::x86_64_asm_read_cr0(); - } value } @@ -217,15 +211,9 @@ mod x86_64 { /// safety through it, e.g. by disabling paging. #[inline] pub unsafe fn write_raw(value: u64) { - #[cfg(feature = "inline_asm")] unsafe { asm!("mov cr0, {}", in(reg) value, options(nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_write_cr0(value); - } } /// Updates CR0 flags. @@ -261,14 +249,9 @@ mod x86_64 { pub fn read_raw() -> u64 { let value: u64; - #[cfg(feature = "inline_asm")] unsafe { asm!("mov {}, cr2", out(reg) value, options(nomem, nostack, preserves_flags)); } - #[cfg(not(feature = "inline_asm"))] - unsafe { - value = crate::asm::x86_64_asm_read_cr2(); - } value } @@ -288,14 +271,9 @@ mod x86_64 { pub fn read_raw() -> (PhysFrame, u16) { let value: u64; - #[cfg(feature = "inline_asm")] unsafe { asm!("mov {}, cr3", out(reg) value, options(nomem, nostack, preserves_flags)); } - #[cfg(not(feature = "inline_asm"))] - unsafe { - value = crate::asm::x86_64_asm_read_cr3(); - } let addr = PhysAddr::new(value & 0x_000f_ffff_ffff_f000); let frame = PhysFrame::containing_address(addr); @@ -349,15 +327,9 @@ mod x86_64 { let addr = frame.start_address(); let value = addr.as_u64() | val as u64; - #[cfg(feature = "inline_asm")] unsafe { asm!("mov cr3, {}", in(reg) value, options(nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_write_cr3(value) - } } } @@ -373,14 +345,9 @@ mod x86_64 { pub fn read_raw() -> u64 { let value: u64; - #[cfg(feature = "inline_asm")] unsafe { asm!("mov {}, cr4", out(reg) value, options(nomem, nostack, preserves_flags)); } - #[cfg(not(feature = "inline_asm"))] - unsafe { - value = crate::asm::x86_64_asm_read_cr4(); - } value } @@ -416,15 +383,9 @@ mod x86_64 { /// flag. #[inline] pub unsafe fn write_raw(value: u64) { - #[cfg(feature = "inline_asm")] unsafe { asm!("mov cr4, {}", in(reg) value, options(nostack, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_write_cr4(value); - } } /// Updates CR4 flags. diff --git a/src/registers/mod.rs b/src/registers/mod.rs index 68ab57081..dfde2439a 100644 --- a/src/registers/mod.rs +++ b/src/registers/mod.rs @@ -11,5 +11,5 @@ pub mod xcontrol; #[allow(deprecated)] pub use crate::instructions::segmentation::{rdfsbase, rdgsbase, wrfsbase, wrgsbase}; -#[cfg(all(feature = "instructions", feature = "inline_asm"))] +#[cfg(feature = "instructions")] pub use crate::instructions::read_rip; diff --git a/src/registers/model_specific.rs b/src/registers/model_specific.rs index a2d285d00..4f55ece89 100644 --- a/src/registers/model_specific.rs +++ b/src/registers/model_specific.rs @@ -127,7 +127,6 @@ mod x86_64 { control::Cr4Flags, segmentation::{Segment, Segment64, CS, SS}, }; - #[cfg(feature = "inline_asm")] use core::arch::asm; impl Msr { @@ -139,24 +138,16 @@ mod x86_64 { /// effects. #[inline] pub unsafe fn read(&self) -> u64 { - #[cfg(feature = "inline_asm")] - { - let (high, low): (u32, u32); - unsafe { - asm!( - "rdmsr", - in("ecx") self.0, - out("eax") low, out("edx") high, - options(nomem, nostack, preserves_flags), - ); - } - ((high as u64) << 32) | (low as u64) - } - - #[cfg(not(feature = "inline_asm"))] + let (high, low): (u32, u32); unsafe { - crate::asm::x86_64_asm_rdmsr(self.0) + asm!( + "rdmsr", + in("ecx") self.0, + out("eax") low, out("edx") high, + options(nomem, nostack, preserves_flags), + ); } + ((high as u64) << 32) | (low as u64) } /// Write 64 bits to msr register. @@ -170,7 +161,6 @@ mod x86_64 { let low = value as u32; let high = (value >> 32) as u32; - #[cfg(feature = "inline_asm")] unsafe { asm!( "wrmsr", @@ -179,11 +169,6 @@ mod x86_64 { options(nostack, preserves_flags), ); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_wrmsr(self.0, low, high); - } } } diff --git a/src/registers/mxcsr.rs b/src/registers/mxcsr.rs index f10812b31..ecb13a933 100644 --- a/src/registers/mxcsr.rs +++ b/src/registers/mxcsr.rs @@ -62,37 +62,24 @@ impl Default for MxCsr { #[cfg(feature = "instructions")] mod x86_64 { use super::*; - #[cfg(feature = "inline_asm")] use core::arch::asm; /// Read the value of MXCSR. #[inline] pub fn read() -> MxCsr { - #[cfg(feature = "inline_asm")] - { - let mut mxcsr: u32 = 0; - unsafe { - asm!("stmxcsr [{}]", in(reg) &mut mxcsr, options(nostack, preserves_flags)); - } - MxCsr::from_bits_truncate(mxcsr) - } - #[cfg(not(feature = "inline_asm"))] + let mut mxcsr: u32 = 0; unsafe { - MxCsr::from_bits_truncate(crate::asm::x86_64_asm_read_mxcsr()) + asm!("stmxcsr [{}]", in(reg) &mut mxcsr, options(nostack, preserves_flags)); } + MxCsr::from_bits_truncate(mxcsr) } /// Write MXCSR. #[inline] pub fn write(mxcsr: MxCsr) { - #[cfg(feature = "inline_asm")] unsafe { asm!("ldmxcsr [{}]", in(reg) &mxcsr, options(nostack, readonly)); } - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_write_mxcsr(mxcsr.bits()); - } } #[cfg(test)] diff --git a/src/registers/rflags.rs b/src/registers/rflags.rs index 4a0c8df3d..1a44365b8 100644 --- a/src/registers/rflags.rs +++ b/src/registers/rflags.rs @@ -65,7 +65,6 @@ bitflags! { #[cfg(feature = "instructions")] mod x86_64 { use super::*; - #[cfg(feature = "inline_asm")] use core::arch::asm; /// Returns the current value of the RFLAGS register. @@ -81,14 +80,9 @@ mod x86_64 { pub fn read_raw() -> u64 { let r: u64; - #[cfg(feature = "inline_asm")] unsafe { asm!("pushfq; pop {}", out(reg) r, options(nomem, preserves_flags)); } - #[cfg(not(feature = "inline_asm"))] - unsafe { - r = crate::asm::x86_64_asm_read_rflags(); - } r } @@ -125,15 +119,9 @@ mod x86_64 { pub unsafe fn write_raw(val: u64) { // HACK: we mark this function as preserves_flags to prevent Rust from restoring // saved flags after the "popf" below. See above note on safety. - #[cfg(feature = "inline_asm")] unsafe { asm!("push {}; popfq", in(reg) val, options(nomem, preserves_flags)); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_write_rflags(val); - } } #[cfg(test)] diff --git a/src/registers/xcontrol.rs b/src/registers/xcontrol.rs index 3f85001c3..655e4ea9d 100644 --- a/src/registers/xcontrol.rs +++ b/src/registers/xcontrol.rs @@ -54,7 +54,6 @@ bitflags! { #[cfg(feature = "instructions")] mod x86_64 { use super::*; - #[cfg(feature = "inline_asm")] use core::arch::asm; impl XCr0 { @@ -67,7 +66,6 @@ mod x86_64 { /// Read the current raw XCR0 value. #[inline] pub fn read_raw() -> u64 { - #[cfg(feature = "inline_asm")] unsafe { let (low, high): (u32, u32); asm!( @@ -78,11 +76,6 @@ mod x86_64 { ); (high as u64) << 32 | (low as u64) } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_xgetbv(0) - } } /// Write XCR0 flags. @@ -144,7 +137,6 @@ mod x86_64 { let low = value as u32; let high = (value >> 32) as u32; - #[cfg(feature = "inline_asm")] unsafe { asm!( "xsetbv", @@ -153,11 +145,6 @@ mod x86_64 { options(nomem, nostack, preserves_flags), ); } - - #[cfg(not(feature = "inline_asm"))] - unsafe { - crate::asm::x86_64_asm_xsetbv(0, low, high); - } } } }