From f08731ec19778322fa32a4993e87dfc5029e7233 Mon Sep 17 00:00:00 2001 From: Nate Catelli Date: Fri, 13 Aug 2021 03:15:41 +0000 Subject: [PATCH 1/7] add step_trait as nightly feature --- Cargo.toml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e476b63d7..5c6346094 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,15 +9,8 @@ authors = [ ] description = "Support for x86_64 specific instructions, registers, and structures." documentation = "https://docs.rs/x86_64" -keywords = [ - "amd64", - "x86", - "x86_64", - "no_std", -] -categories = [ - "no-std", -] +keywords = ["amd64", "x86", "x86_64", "no_std"] +categories = ["no-std"] license = "MIT/Apache-2.0" name = "x86_64" readme = "README.md" @@ -37,16 +30,17 @@ cc = { version = "1.0.37", optional = true } default = [ "nightly", "instructions" ] instructions = [] external_asm = [ "cc" ] -nightly = [ "inline_asm", "const_fn", "abi_x86_interrupt", "doc_cfg" ] +nightly = [ "inline_asm", "const_fn", "abi_x86_interrupt", "doc_cfg", "step_trait" ] inline_asm = [] abi_x86_interrupt = [] const_fn = [] doc_cfg = [] +step_trait = [] [package.metadata.release] no-dev-version = true pre-release-replacements = [ - { file="Changelog.md", search="# Unreleased", replace="# Unreleased\n\n# {{version}} – {{date}}", exactly=1 }, + { file = "Changelog.md", search = "# Unreleased", replace = "# Unreleased\n\n# {{version}} – {{date}}", exactly = 1 }, ] pre-release-commit-message = "Bump version to {{version}}" disable-push = true From 943719798280801f9b77458d649cde3286485b23 Mon Sep 17 00:00:00 2001 From: Nate Catelli Date: Fri, 13 Aug 2021 04:20:34 +0000 Subject: [PATCH 2/7] naive pass at implementing Step for PhysFrame --- src/lib.rs | 2 +- src/structures/paging/frame.rs | 51 ++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 73a6c5061..596e26a3c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,7 @@ #![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)] +#![cfg_attr(feature = "step_trait", feature(step_trait))] #![deny(missing_debug_implementations)] pub use crate::addr::{align_down, align_up, PhysAddr, VirtAddr}; diff --git a/src/structures/paging/frame.rs b/src/structures/paging/frame.rs index f125404fc..aa875861e 100644 --- a/src/structures/paging/frame.rs +++ b/src/structures/paging/frame.rs @@ -132,6 +132,57 @@ impl Sub> for PhysFrame { } } +#[cfg(feature = "step_trait")] +impl core::iter::Step for PhysFrame { + fn steps_between(start: &Self, end: &Self) -> Option { + if *start <= *end { + Some((*end - *start) as usize) + } else { + None + } + } + + fn forward_checked(start: Self, count: usize) -> Option { + use core::convert::TryFrom; + + match u64::try_from(count) { + Ok(n) => match start.start_address().as_u64().overflowing_add(n * S::SIZE) { + (_, true) => None, + (start_addr, false) => Self::from_start_address(PhysAddr::new(start_addr)).ok(), + }, + Err(_) => None, // if n is out of range, `unsigned_start + n` + } + } + + fn backward_checked(start: Self, count: usize) -> Option { + use core::convert::TryFrom; + + match u64::try_from(count) { + Ok(n) => match start.start_address().as_u64().overflowing_sub(n * S::SIZE) { + (_, true) => None, + (start_addr, false) => Self::from_start_address(PhysAddr::new(start_addr)).ok(), + }, + Err(_) => None, // if n is out of range, `unsigned_start + n` + } + } + + fn forward(start: Self, count: usize) -> Self { + core::iter::Step::forward_checked(start, count).expect("overflow in `Step::forward`") + } + + unsafe fn forward_unchecked(start: Self, count: usize) -> Self { + core::iter::Step::forward(start, count) + } + + fn backward(start: Self, count: usize) -> Self { + core::iter::Step::backward_checked(start, count).expect("overflow in `Step::backward`") + } + + unsafe fn backward_unchecked(start: Self, count: usize) -> Self { + core::iter::Step::backward(start, count) + } +} + /// An range of physical memory frames, exclusive the upper bound. #[derive(Clone, Copy, PartialEq, Eq)] #[repr(C)] From 97f452b78fd9c01bcf40b535b7dd00eb0b45f1b2 Mon Sep 17 00:00:00 2001 From: Nate Catelli Date: Fri, 13 Aug 2021 04:33:05 +0000 Subject: [PATCH 3/7] use checked_* methods --- src/structures/paging/frame.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/structures/paging/frame.rs b/src/structures/paging/frame.rs index aa875861e..c4b24f574 100644 --- a/src/structures/paging/frame.rs +++ b/src/structures/paging/frame.rs @@ -146,10 +146,11 @@ impl core::iter::Step for PhysFrame { use core::convert::TryFrom; match u64::try_from(count) { - Ok(n) => match start.start_address().as_u64().overflowing_add(n * S::SIZE) { - (_, true) => None, - (start_addr, false) => Self::from_start_address(PhysAddr::new(start_addr)).ok(), - }, + Ok(n) => start + .start_address() + .as_u64() + .checked_add(n * S::SIZE) + .and_then(|start_addr| Self::from_start_address(PhysAddr::new(start_addr)).ok()), Err(_) => None, // if n is out of range, `unsigned_start + n` } } @@ -158,10 +159,11 @@ impl core::iter::Step for PhysFrame { use core::convert::TryFrom; match u64::try_from(count) { - Ok(n) => match start.start_address().as_u64().overflowing_sub(n * S::SIZE) { - (_, true) => None, - (start_addr, false) => Self::from_start_address(PhysAddr::new(start_addr)).ok(), - }, + Ok(n) => start + .start_address() + .as_u64() + .checked_sub(n * S::SIZE) + .and_then(|start_addr| Self::from_start_address(PhysAddr::new(start_addr)).ok()), Err(_) => None, // if n is out of range, `unsigned_start + n` } } From 644cc685707a894807999127386e0b5876f5efaf Mon Sep 17 00:00:00 2001 From: Nate Catelli Date: Fri, 13 Aug 2021 04:43:29 +0000 Subject: [PATCH 4/7] Revert autoformating of Cargo.toml --- Cargo.toml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5c6346094..2b99757ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,15 @@ authors = [ ] description = "Support for x86_64 specific instructions, registers, and structures." documentation = "https://docs.rs/x86_64" -keywords = ["amd64", "x86", "x86_64", "no_std"] -categories = ["no-std"] +keywords = [ + "amd64", + "x86", + "x86_64", + "no_std", +] +categories = [ + "no-std", +] license = "MIT/Apache-2.0" name = "x86_64" readme = "README.md" @@ -40,7 +47,7 @@ step_trait = [] [package.metadata.release] no-dev-version = true pre-release-replacements = [ - { file = "Changelog.md", search = "# Unreleased", replace = "# Unreleased\n\n# {{version}} – {{date}}", exactly = 1 }, + { file="Changelog.md", search="# Unreleased", replace="# Unreleased\n\n# {{version}} – {{date}}", exactly=1 }, ] pre-release-commit-message = "Bump version to {{version}}" disable-push = true From 7555a5eafd5304f9fe4daa72fcdf010d008c4c58 Mon Sep 17 00:00:00 2001 From: Nate Catelli Date: Thu, 19 Aug 2021 15:28:41 +0000 Subject: [PATCH 5/7] remove default traits per feedback --- src/structures/paging/frame.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/structures/paging/frame.rs b/src/structures/paging/frame.rs index c4b24f574..7da40d5fa 100644 --- a/src/structures/paging/frame.rs +++ b/src/structures/paging/frame.rs @@ -167,22 +167,6 @@ impl core::iter::Step for PhysFrame { Err(_) => None, // if n is out of range, `unsigned_start + n` } } - - fn forward(start: Self, count: usize) -> Self { - core::iter::Step::forward_checked(start, count).expect("overflow in `Step::forward`") - } - - unsafe fn forward_unchecked(start: Self, count: usize) -> Self { - core::iter::Step::forward(start, count) - } - - fn backward(start: Self, count: usize) -> Self { - core::iter::Step::backward_checked(start, count).expect("overflow in `Step::backward`") - } - - unsafe fn backward_unchecked(start: Self, count: usize) -> Self { - core::iter::Step::backward(start, count) - } } /// An range of physical memory frames, exclusive the upper bound. From 8656f8f1271692ac50e87ba1ffafced9e29d8678 Mon Sep 17 00:00:00 2001 From: Nate Catelli Date: Thu, 19 Aug 2021 15:35:57 +0000 Subject: [PATCH 6/7] Implement step for PhysAddr --- src/addr.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/addr.rs b/src/addr.rs index 1c93f0219..01df03900 100644 --- a/src/addr.rs +++ b/src/addr.rs @@ -529,6 +529,25 @@ impl Sub for PhysAddr { } } +#[cfg(feature = "step_trait")] +impl core::iter::Step for PhysAddr { + fn steps_between(start: &Self, end: &Self) -> Option { + if *start <= *end { + Some((*end - *start) as usize) + } else { + None + } + } + + fn forward_checked(start: Self, count: usize) -> Option { + start.as_u64().checked_add(count as u64).map(PhysAddr::new) + } + + fn backward_checked(start: Self, count: usize) -> Option { + start.as_u64().checked_sub(count as u64).map(PhysAddr::new) + } +} + /// Align address downwards. /// /// Returns the greatest `x` with alignment `align` so that `x <= addr`. From 9fd56702ad752725357ff7c12a39f625c8fa36c5 Mon Sep 17 00:00:00 2001 From: Nate Catelli Date: Thu, 19 Aug 2021 15:43:21 +0000 Subject: [PATCH 7/7] Proxy PhysFram step impl to PhysAddr impl --- src/structures/paging/frame.rs | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/src/structures/paging/frame.rs b/src/structures/paging/frame.rs index 7da40d5fa..2626d9292 100644 --- a/src/structures/paging/frame.rs +++ b/src/structures/paging/frame.rs @@ -135,37 +135,17 @@ impl Sub> for PhysFrame { #[cfg(feature = "step_trait")] impl core::iter::Step for PhysFrame { fn steps_between(start: &Self, end: &Self) -> Option { - if *start <= *end { - Some((*end - *start) as usize) - } else { - None - } + PhysAddr::steps_between(&start.start_address, &end.start_address) } fn forward_checked(start: Self, count: usize) -> Option { - use core::convert::TryFrom; - - match u64::try_from(count) { - Ok(n) => start - .start_address() - .as_u64() - .checked_add(n * S::SIZE) - .and_then(|start_addr| Self::from_start_address(PhysAddr::new(start_addr)).ok()), - Err(_) => None, // if n is out of range, `unsigned_start + n` - } + PhysAddr::forward_checked(start.start_address, count) + .and_then(|start_addr| Self::from_start_address(start_addr).ok()) } fn backward_checked(start: Self, count: usize) -> Option { - use core::convert::TryFrom; - - match u64::try_from(count) { - Ok(n) => start - .start_address() - .as_u64() - .checked_sub(n * S::SIZE) - .and_then(|start_addr| Self::from_start_address(PhysAddr::new(start_addr)).ok()), - Err(_) => None, // if n is out of range, `unsigned_start + n` - } + PhysAddr::backward_checked(start.start_address, count) + .and_then(|start_addr| Self::from_start_address(start_addr).ok()) } }