diff --git a/src/addr.rs b/src/addr.rs index 19031986..8afe53f3 100644 --- a/src/addr.rs +++ b/src/addr.rs @@ -495,7 +495,15 @@ impl PhysAddr { where U: Into, { - PhysAddr(align_down(self.0, align.into())) + self.align_down_u64(align.into()) + } + + /// Aligns the physical address downwards to the given alignment. + /// + /// See the `align_down` function for more information. + #[inline] + pub(crate) const fn align_down_u64(self, align: u64) -> Self { + PhysAddr(align_down(self.0, align)) } /// Checks whether the physical address has the demanded alignment. @@ -504,7 +512,13 @@ impl PhysAddr { where U: Into, { - self.align_down(align) == self + self.is_aligned_u64(align.into()) + } + + /// Checks whether the physical address has the demanded alignment. + #[inline] + pub(crate) const fn is_aligned_u64(self, align: u64) -> bool { + self.align_down_u64(align).as_u64() == self.as_u64() } } diff --git a/src/registers/model_specific.rs b/src/registers/model_specific.rs index 07504878..0471bfae 100644 --- a/src/registers/model_specific.rs +++ b/src/registers/model_specific.rs @@ -357,11 +357,11 @@ mod x86_64 { /// /// # Returns /// - Field 1 (SYSRET): The CS selector is set to this field + 16. SS.Sel is set to - /// this field + 8. Because SYSRET always returns to CPL 3, the - /// RPL bits 1:0 should be initialized to 11b. + /// this field + 8. Because SYSRET always returns to CPL 3, the + /// RPL bits 1:0 should be initialized to 11b. /// - Field 2 (SYSCALL): This field is copied directly into CS.Sel. SS.Sel is set to - /// this field + 8. Because SYSCALL always switches to CPL 0, the RPL bits - /// 33:32 should be initialized to 00b. + /// this field + 8. Because SYSCALL always switches to CPL 0, the RPL bits + /// 33:32 should be initialized to 00b. #[inline] pub fn read_raw() -> (u16, u16) { let msr_value = unsafe { Self::MSR.read() }; @@ -398,11 +398,11 @@ mod x86_64 { /// /// # Parameters /// - sysret: The CS selector is set to this field + 16. SS.Sel is set to - /// this field + 8. Because SYSRET always returns to CPL 3, the - /// RPL bits 1:0 should be initialized to 11b. + /// this field + 8. Because SYSRET always returns to CPL 3, the + /// RPL bits 1:0 should be initialized to 11b. /// - syscall: This field is copied directly into CS.Sel. SS.Sel is set to - /// this field + 8. Because SYSCALL always switches to CPL 0, the RPL bits - /// 33:32 should be initialized to 00b. + /// this field + 8. Because SYSCALL always switches to CPL 0, the RPL bits + /// 33:32 should be initialized to 00b. /// /// # Safety /// diff --git a/src/structures/idt.rs b/src/structures/idt.rs index 2d9beb5a..4a92bacf 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -153,9 +153,9 @@ pub struct InterruptDescriptorTable { /// is enabled. /// - Execution of any legacy SSE instruction when `CR4.OSFXSR` is cleared to 0. /// - Execution of any SSE instruction (uses `YMM`/`XMM` registers), or 64-bit media - /// instruction (uses `MMXTM` registers) when `CR0.EM` = 1. + /// instruction (uses `MMXTM` registers) when `CR0.EM` = 1. /// - Execution of any SSE floating-point instruction (uses `YMM`/`XMM` registers) that - /// causes a numeric exception when `CR4.OSXMMEXCPT` = 0. + /// causes a numeric exception when `CR4.OSXMMEXCPT` = 0. /// - Use of the `DR4` or `DR5` debug registers when `CR4.DE` = 1. /// - Execution of `RSM` when not in `SMM` mode. /// @@ -503,7 +503,7 @@ impl InterruptDescriptorTable { /// /// - `self` is never destroyed. /// - `self` always stays at the same memory location. It is recommended to wrap it in - /// a `Box`. + /// a `Box`. /// #[cfg(all(feature = "instructions", target_arch = "x86_64"))] #[inline] @@ -1642,7 +1642,7 @@ mod test { #[test] fn entry_derive_test() { - fn foo(_: impl Clone + Copy + PartialEq + fmt::Debug) {} + fn foo(_: impl Copy + PartialEq + fmt::Debug) {} foo(Entry:: { pointer_low: 0, @@ -1667,9 +1667,7 @@ mod test { }); unsafe { - frame - .as_mut() - .update(|f| f.instruction_pointer = f.instruction_pointer + 2u64); + frame.as_mut().update(|f| f.instruction_pointer += 2u64); } } } diff --git a/src/structures/paging/frame.rs b/src/structures/paging/frame.rs index 6cae8fab..1e5862b6 100644 --- a/src/structures/paging/frame.rs +++ b/src/structures/paging/frame.rs @@ -21,8 +21,9 @@ impl PhysFrame { /// /// Returns an error if the address is not correctly aligned (i.e. is not a valid frame start). #[inline] + #[rustversion::attr(since(1.61), const)] pub fn from_start_address(address: PhysAddr) -> Result { - if !address.is_aligned(S::SIZE) { + if !address.is_aligned_u64(S::SIZE) { return Err(AddressNotAligned); } @@ -46,9 +47,10 @@ impl PhysFrame { /// Returns the frame that contains the given physical address. #[inline] + #[rustversion::attr(since(1.61), const)] pub fn containing_address(address: PhysAddr) -> Self { PhysFrame { - start_address: address.align_down(S::SIZE), + start_address: address.align_down_u64(S::SIZE), size: PhantomData, } } diff --git a/src/structures/paging/page.rs b/src/structures/paging/page.rs index e05b576d..445abd26 100644 --- a/src/structures/paging/page.rs +++ b/src/structures/paging/page.rs @@ -23,17 +23,17 @@ pub trait PageSize: Copy + Eq + PartialOrd + Ord + Sealed { pub trait NotGiantPageSize: PageSize {} /// A standard 4KiB page. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Size4KiB {} /// A “huge” 2MiB page. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Size2MiB {} /// A “giant” 1GiB page. /// /// (Only available on newer x86_64 CPUs.) -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Size1GiB {} impl PageSize for Size4KiB { @@ -429,6 +429,15 @@ impl fmt::Display for AddressNotAligned { mod tests { use super::*; + fn test_is_hash() {} + + #[test] + pub fn test_page_is_hash() { + test_is_hash::>(); + test_is_hash::>(); + test_is_hash::>(); + } + #[test] pub fn test_page_ranges() { let page_size = Size4KiB::SIZE;