diff --git a/src/controlregs.rs b/src/controlregs.rs index 70b1c993..b09a48ae 100644 --- a/src/controlregs.rs +++ b/src/controlregs.rs @@ -1,6 +1,8 @@ //! Functions to read and write control registers. //! See Intel Vol. 3a Section 2.5, especially Figure 2-7. +use arch::{_xgetbv, _xsetbv}; + bitflags! { pub struct Cr0: usize { const CR0_ENABLE_PAGING = 1 << 31; @@ -102,16 +104,11 @@ pub unsafe fn cr4_write(val: Cr4) { /// Read Extended Control Register XCR0. /// Only supported if CR4_ENABLE_OS_XSAVE is set. pub unsafe fn xcr0() -> Xcr0 { - let high: u32; - let low: u32; - asm!("xgetbv" : "={eax}"(low), "={edx}"(high) : "{ecx}"(0)); - Xcr0::from_bits_truncate((high as u64) << 32 | low as u64) + Xcr0::from_bits_truncate(_xgetbv(0)) } /// Write to Extended Control Register XCR0. /// Only supported if CR4_ENABLE_OS_XSAVE is set. pub unsafe fn xcr0_write(val: Xcr0) { - let high: u32 = (val.bits >> 32) as u32; - let low: u32 = val.bits as u32; - asm!("xsetbv" :: "{eax}"(low), "{ecx}"(0), "{edx}"(high)); + _xsetbv(0, val.bits); } diff --git a/src/lib.rs b/src/lib.rs index 90592a20..814952b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,11 @@ extern crate phf; #[macro_use] extern crate std; +#[cfg(target_arch = "x86")] +use core::arch::x86 as arch; +#[cfg(target_arch = "x86_64")] +use core::arch::x86_64 as arch; + macro_rules! check_flag { ($doc:meta, $fun:ident, $flag:expr) => ( #[$doc] diff --git a/src/time.rs b/src/time.rs index eff567d0..ba458d0c 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1,5 +1,8 @@ //! Functions to read time stamp counters on x86. +use core::mem; +use arch::{_rdtsc, __rdtscp}; + /// Read the time stamp counter. /// /// The RDTSC instruction is not a serializing instruction. @@ -13,13 +16,8 @@ /// # Safety /// * Causes a GP fault if the TSD flag in register CR4 is set and the CPL /// is greater than 0. -#[allow(unused_mut)] pub unsafe fn rdtsc() -> u64 { - let mut low: u32; - let mut high: u32; - - asm!("rdtsc" : "={eax}" (low), "={edx}" (high)); - ((high as u64) << 32) | (low as u64) + mem::transmute(_rdtsc()) } /// Read the time stamp counter. @@ -35,11 +33,7 @@ pub unsafe fn rdtsc() -> u64 { /// # Safety /// * Causes a GP fault if the TSD flag in register CR4 is set and the /// CPL is greater than 0. -#[allow(unused_mut)] pub unsafe fn rdtscp() -> u64 { - let mut low: u32; - let mut high: u32; - - asm!("rdtscp" : "={eax}" (low), "={edx}" (high) ::: "volatile"); - ((high as u64) << 32) | (low as u64) + let mut _aux = 0; + __rdtscp(&mut _aux) }