diff --git a/Cargo.lock b/Cargo.lock index a703a90..d0b76fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "libsys" -version = "0.3.1" +version = "0.3.2" dependencies = [ "num_enum", "spin", diff --git a/Cargo.toml b/Cargo.toml index 2013ff8..7dba4e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsys" -version = "0.3.1" +version = "0.3.2" edition = "2024" [dependencies] diff --git a/src/constants/mod.rs b/src/constants/mod.rs index 6a14482..711428a 100644 --- a/src/constants/mod.rs +++ b/src/constants/mod.rs @@ -10,14 +10,6 @@ pub use x86_64::*; #[cfg(not(test))] static PAGING_DEPTH: spin::Once> = spin::Once::new(); -pub fn get_paging_depth() -> NonZero { - cfg_select! { - // Safety: Value is non-zero. - test => { unsafe { NonZero::new_unchecked(4) } } - _ => { *PAGING_DEPTH.get().expect("paging depth has not been set") } - } -} - /// Sets the current paging depth. /// /// # Safety @@ -33,3 +25,14 @@ pub fn get_paging_depth() -> NonZero { pub unsafe fn set_paging_depth(paging_depth: NonZero) { PAGING_DEPTH.call_once(|| paging_depth); } + +pub fn get_paging_depth() -> NonZero { + cfg_select! { + test => { + // Safety: Value is non-zero. + unsafe { NonZero::new_unchecked(4) } + } + + _ => { *PAGING_DEPTH.get().expect("paging depth has not been set") } + } +} diff --git a/src/constants/x86_64.rs b/src/constants/x86_64.rs index 0dfc421..385f71b 100644 --- a/src/constants/x86_64.rs +++ b/src/constants/x86_64.rs @@ -4,63 +4,65 @@ use core::num::NonZero; /// Bit shift required to offset page indexes. #[must_use] pub const fn page_bits() -> NonZero { - NonZero::::new(12).unwrap() + // Safety: Value is non-zero. + unsafe { NonZero::::new_unchecked(12) } } /// Bit shift required to offset large page indexes. #[must_use] pub const fn large_page_bits() -> NonZero { - page_bits().checked_add(table_index_bits().get()).unwrap() + // Safety: Value is non-zero. + unsafe { NonZero::::new_unchecked(page_bits().get() + table_index_bits().get()) } } /// Bit shift required to offset huge page indexes. #[must_use] pub const fn huge_page_bits() -> NonZero { - large_page_bits() - .checked_add(table_index_bits().get()) - .unwrap() + // Safety: Value is non-zero. + unsafe { NonZero::::new_unchecked(large_page_bits().get() + table_index_bits().get()) } } /// The size of a page in bytes. #[must_use] pub const fn page_size() -> usize { - 1usize.checked_shl(page_bits().get()).unwrap() + 1 << page_bits().get() } /// The size of a large page in bytes. #[must_use] pub const fn large_page_size() -> usize { - 1usize.checked_shl(large_page_bits().get()).unwrap() + 1 << large_page_bits().get() } /// The size of a huge page in bytes. #[must_use] pub const fn huge_page_size() -> usize { - 1usize.checked_shl(huge_page_bits().get()).unwrap() + 1 << huge_page_bits().get() } /// Bit-mask of non-index page bytes. #[must_use] pub const fn page_mask() -> usize { - page_size().checked_sub(1).unwrap() + page_size() - 1 } /// Bit-mask of non-index large page bytes. #[must_use] pub const fn large_page_mask() -> usize { - large_page_size().checked_sub(1).unwrap() + large_page_size() - 1 } /// Bit-mask of non-index huge page bytes. #[must_use] pub const fn huge_page_mask() -> usize { - huge_page_size().checked_sub(1).unwrap() + huge_page_size() - 1 } /// Shift (in bits) of a page table index. #[must_use] pub const fn table_index_bits() -> NonZero { - NonZero::::new(9).unwrap() + // Safety: Value is non-zero. + unsafe { NonZero::::new_unchecked(9) } } /// Size (in bytes) of a page table index. @@ -72,25 +74,26 @@ pub const fn table_index_size() -> usize { /// Bit-mask of a page table index. #[must_use] pub const fn table_index_mask() -> usize { - table_index_size().checked_sub(1).unwrap() + table_index_size() - 1 } /// Number of bits in a canonical physical address. #[must_use] pub const fn physical_address_bits() -> NonZero { - NonZero::::new(52).unwrap() + // Safety: Value is non-zero. + unsafe { NonZero::::new_unchecked(52) } } /// The maximum physical address size (in bytes). #[must_use] pub const fn physical_address_size() -> usize { - 1usize.checked_shl(physical_address_bits().get()).unwrap() + 1 << physical_address_bits().get() } /// Bit-mask of canonical physical bits. #[must_use] pub const fn physical_address_mask() -> usize { - physical_address_size().checked_sub(1).unwrap() + physical_address_size() - 1 } /// Checks if the provided `physical_address` is canonical. @@ -116,11 +119,13 @@ pub fn is_virtual_address_canonical(virtual_address: usize) -> bool { matches!(virtual_address >> sign_extension_check_shift, 0 | 0x1FFFF) } +/// Truncates all non-canonical physical bits from an address. #[must_use] pub fn truncate_physical_address(address: usize) -> usize { address & physical_address_mask() } +/// Truncates all non-canonical virtual bits from an address. #[must_use] #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] pub fn truncate_virtual_address(address: usize) -> usize {