aboutsummaryrefslogtreecommitdiff
path: root/rust/kernel/ptr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/kernel/ptr.rs')
-rw-r--r--rust/kernel/ptr.rs64
1 files changed, 60 insertions, 4 deletions
diff --git a/rust/kernel/ptr.rs b/rust/kernel/ptr.rs
index e3893ed04049..3f3e529e9f58 100644
--- a/rust/kernel/ptr.rs
+++ b/rust/kernel/ptr.rs
@@ -2,10 +2,16 @@
//! Types and functions to work with pointers and addresses.
-use core::mem::align_of;
+pub mod projection;
+pub use crate::project_pointer as project;
+
+use core::mem::{
+ align_of,
+ size_of, //
+};
use core::num::NonZero;
-use crate::build_assert;
+use crate::const_assert;
/// Type representing an alignment, which is always a power of two.
///
@@ -40,7 +46,7 @@ impl Alignment {
/// ```
#[inline(always)]
pub const fn new<const ALIGN: usize>() -> Self {
- build_assert!(
+ const_assert!(
ALIGN.is_power_of_two(),
"Provided alignment is not a power of two."
);
@@ -81,7 +87,6 @@ impl Alignment {
/// This is equivalent to [`align_of`], but with the return value provided as an [`Alignment`].
#[inline(always)]
pub const fn of<T>() -> Self {
- #![allow(clippy::incompatible_msrv)]
// This cannot panic since alignments are always powers of two.
//
// We unfortunately cannot use `new` as it would require the `generic_const_exprs` feature.
@@ -225,3 +230,54 @@ macro_rules! impl_alignable_uint {
}
impl_alignable_uint!(u8, u16, u32, u64, usize);
+
+/// Trait to represent compile-time known size information.
+///
+/// This is a generalization of [`size_of`] that works for dynamically sized types.
+pub trait KnownSize {
+ /// Get the size of an object of this type in bytes, with the metadata of the given pointer.
+ fn size(p: *const Self) -> usize;
+}
+
+impl<T> KnownSize for T {
+ #[inline(always)]
+ fn size(_: *const Self) -> usize {
+ size_of::<T>()
+ }
+}
+
+impl<T> KnownSize for [T] {
+ #[inline(always)]
+ fn size(p: *const Self) -> usize {
+ p.len() * size_of::<T>()
+ }
+}
+
+/// Aligns `value` up to `align`.
+///
+/// This is the const-compatible equivalent of [`Alignable::align_up`].
+///
+/// Returns [`None`] on overflow.
+///
+/// # Examples
+///
+/// ```
+/// use kernel::{
+/// ptr::{
+/// const_align_up,
+/// Alignment, //
+/// },
+/// sizes::SZ_4K, //
+/// };
+///
+/// assert_eq!(const_align_up(0x4f, Alignment::new::<16>()), Some(0x50));
+/// assert_eq!(const_align_up(0x40, Alignment::new::<16>()), Some(0x40));
+/// assert_eq!(const_align_up(1, Alignment::new::<SZ_4K>()), Some(SZ_4K));
+/// ```
+#[inline(always)]
+pub const fn const_align_up(value: usize, align: Alignment) -> Option<usize> {
+ match value.checked_add(align.as_usize() - 1) {
+ Some(v) => Some(v & align.mask()),
+ None => None,
+ }
+}