From 706f7d1e6751aefaffe97cc678ca6049a82bd3b6 Mon Sep 17 00:00:00 2001 From: Yuekai Jia Date: Sat, 15 Apr 2023 16:51:09 +0800 Subject: [PATCH] doc: add documents of some crates --- Cargo.toml | 7 +++- src/lib.rs | 105 +++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 90 insertions(+), 22 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7a7beb8..b20cd08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,10 @@ name = "memory_addr" version = "0.1.0" edition = "2021" authors = ["Yuekai Jia "] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +description = "Wrappers and helper functions for physical and virtual addresses" +license = "GPL-3.0-or-later OR Apache-2.0" +homepage = "https://github.com/rcore-os/arceos" +repository = "https://github.com/rcore-os/arceos/tree/main/crates/memory_addr" +documentation = "https://rcore-os.github.io/arceos/memory_addr/index.html" [dependencies] diff --git a/src/lib.rs b/src/lib.rs index ad1dece..2b65630 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +//! Wrappers and helper functions for physical and virtual memory addresses. + #![no_std] #![feature(const_mut_refs)] #![feature(const_trait_impl)] @@ -5,8 +7,14 @@ use core::fmt; use core::ops::{Add, AddAssign, Sub, SubAssign}; +/// The size of a 4K page (4096 bytes). pub const PAGE_SIZE_4K: usize = 0x1000; +/// Align address downwards. +/// +/// Returns the greatest `x` with alignment `align` so that `x <= addr`. +/// +/// The alignment must be a power of two. #[inline] pub const fn align_down(addr: usize, align: U) -> usize where @@ -15,6 +23,11 @@ where addr & !(align.into() - 1) } +/// Align address upwards. +/// +/// Returns the smallest `x` with alignment `align` so that `x >= addr`. +/// +/// The alignment must be a power of two. #[inline] pub const fn align_up(addr: usize, align: U) -> usize where @@ -24,6 +37,9 @@ where (addr + align - 1) & !(align - 1) } +/// Returns the offset of the address within the alignment. +/// +/// Equivalent to `addr % align`, but the alignment must be a power of two. #[inline] pub const fn align_offset(addr: usize, align: U) -> usize where @@ -32,6 +48,9 @@ where addr & (align.into() - 1) } +/// Checks whether the address has the demanded alignment. +/// +/// Equivalent to `addr % align == 0`, but the alignment must be a power of two. #[inline] pub const fn is_aligned(addr: usize, align: U) -> bool where @@ -40,158 +59,204 @@ where align_offset(addr, align) == 0 } +/// Align address downwards to 4096 (bytes). #[inline] pub const fn align_down_4k(addr: usize) -> usize { align_down(addr, PAGE_SIZE_4K) } +/// Align address upwards to 4096 (bytes). #[inline] pub const fn align_up_4k(addr: usize) -> usize { align_up(addr, PAGE_SIZE_4K) } +/// Returns the offset of the address within a 4K-sized page. #[inline] pub const fn align_offset_4k(addr: usize) -> usize { align_offset(addr, PAGE_SIZE_4K) } +/// Checks whether the address is 4K-aligned. #[inline] pub const fn is_aligned_4k(addr: usize) -> bool { is_aligned(addr, PAGE_SIZE_4K) } +/// A physical memory address. +/// +/// It's a wrapper type around an `usize`. #[repr(transparent)] #[derive(Copy, Clone, Default, Ord, PartialOrd, Eq, PartialEq)] pub struct PhysAddr(usize); +/// A virtual memory address. +/// +/// It's a wrapper type around an `usize`. #[repr(transparent)] #[derive(Copy, Clone, Default, Ord, PartialOrd, Eq, PartialEq)] pub struct VirtAddr(usize); impl PhysAddr { + /// Converts the address to an `usize`. #[inline] - pub const fn as_usize(&self) -> usize { + pub const fn as_usize(self) -> usize { self.0 } + /// Aligns the address downwards to the given alignment. + /// + /// See the [`align_down`] function for more information. #[inline] - pub const fn align_down(&self, align: U) -> Self + pub const fn align_down(self, align: U) -> Self where U: ~const Into, { Self(align_down(self.0, align)) } + /// Aligns the address upwards to the given alignment. + /// + /// See the [`align_up`] function for more information. #[inline] - pub const fn align_up(&self, align: U) -> Self + pub const fn align_up(self, align: U) -> Self where U: ~const Into, { Self(align_up(self.0, align)) } + /// Returns the offset of the address within the given alignment. + /// + /// See the [`align_offset`] function for more information. #[inline] - pub const fn align_offset(&self, align: U) -> usize + pub const fn align_offset(self, align: U) -> usize where U: ~const Into, { align_offset(self.0, align) } + /// Checks whether the address has the demanded alignment. + /// + /// See the [`is_aligned`] function for more information. #[inline] - pub const fn is_aligned(&self, align: U) -> bool + pub const fn is_aligned(self, align: U) -> bool where U: ~const Into, { is_aligned(self.0, align) } + /// Aligns the address downwards to 4096 (bytes). #[inline] - pub const fn align_down_4k(&self) -> Self { + pub const fn align_down_4k(self) -> Self { self.align_down(PAGE_SIZE_4K) } + /// Aligns the address upwards to 4096 (bytes). #[inline] - pub const fn align_up_4k(&self) -> Self { + pub const fn align_up_4k(self) -> Self { self.align_up(PAGE_SIZE_4K) } + /// Returns the offset of the address within a 4K-sized page. #[inline] - pub const fn align_offset_4k(&self) -> usize { + pub const fn align_offset_4k(self) -> usize { self.align_offset(PAGE_SIZE_4K) } + /// Checks whether the address is 4K-aligned. #[inline] - pub const fn is_aligned_4k(&self) -> bool { + pub const fn is_aligned_4k(self) -> bool { self.is_aligned(PAGE_SIZE_4K) } } impl VirtAddr { + /// Converts the address to an `usize`. #[inline] - pub const fn as_usize(&self) -> usize { + pub const fn as_usize(self) -> usize { self.0 } + /// Converts the virtual address to a raw pointer. #[inline] - pub const fn as_ptr(&self) -> *const u8 { + pub const fn as_ptr(self) -> *const u8 { self.0 as *const u8 } + /// Converts the virtual address to a mutable raw pointer. #[inline] - pub const fn as_mut_ptr(&self) -> *mut u8 { + pub const fn as_mut_ptr(self) -> *mut u8 { self.0 as *mut u8 } + /// Aligns the address downwards to the given alignment. + /// + /// See the [`align_down`] function for more information. #[inline] - pub const fn align_down(&self, align: U) -> Self + pub const fn align_down(self, align: U) -> Self where U: ~const Into, { Self(align_down(self.0, align)) } + /// Aligns the address upwards to the given alignment. + /// + /// See the [`align_up`] function for more information. #[inline] - pub const fn align_up(&self, align: U) -> Self + pub const fn align_up(self, align: U) -> Self where U: ~const Into, { Self(align_up(self.0, align)) } + /// Returns the offset of the address within the given alignment. + /// + /// See the [`align_offset`] function for more information. #[inline] - pub const fn align_offset(&self, align: U) -> usize + pub const fn align_offset(self, align: U) -> usize where U: ~const Into, { align_offset(self.0, align) } + ///Checks whether the address has the demanded alignment. + /// + /// See the [`is_aligned`] function for more information. #[inline] - pub const fn is_aligned(&self, align: U) -> bool + pub const fn is_aligned(self, align: U) -> bool where U: ~const Into, { is_aligned(self.0, align) } + /// Aligns the address downwards to 4096 (bytes). #[inline] - pub const fn align_down_4k(&self) -> Self { + pub const fn align_down_4k(self) -> Self { self.align_down(PAGE_SIZE_4K) } + /// Aligns the address upwards to 4096 (bytes). #[inline] - pub const fn align_up_4k(&self) -> Self { + pub const fn align_up_4k(self) -> Self { self.align_up(PAGE_SIZE_4K) } + /// Returns the offset of the address within a 4K-sized page. #[inline] - pub const fn align_offset_4k(&self) -> usize { + pub const fn align_offset_4k(self) -> usize { self.align_offset(PAGE_SIZE_4K) } + /// Checks whether the address is 4K-aligned. #[inline] - pub const fn is_aligned_4k(&self) -> bool { + pub const fn is_aligned_4k(self) -> bool { self.is_aligned(PAGE_SIZE_4K) } }