Skip to content

Commit

Permalink
doc: add documents of some crates
Browse files Browse the repository at this point in the history
  • Loading branch information
equation314 committed Apr 15, 2023
1 parent e1b9619 commit 706f7d1
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 22 deletions.
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ name = "memory_addr"
version = "0.1.0"
edition = "2021"
authors = ["Yuekai Jia <[email protected]>"]

# 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]
105 changes: 85 additions & 20 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
//! Wrappers and helper functions for physical and virtual memory addresses.
#![no_std]
#![feature(const_mut_refs)]
#![feature(const_trait_impl)]

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<U>(addr: usize, align: U) -> usize
where
Expand All @@ -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<U>(addr: usize, align: U) -> usize
where
Expand All @@ -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<U>(addr: usize, align: U) -> usize
where
Expand All @@ -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<U>(addr: usize, align: U) -> bool
where
Expand All @@ -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<U>(&self, align: U) -> Self
pub const fn align_down<U>(self, align: U) -> Self
where
U: ~const Into<usize>,
{
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<U>(&self, align: U) -> Self
pub const fn align_up<U>(self, align: U) -> Self
where
U: ~const Into<usize>,
{
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<U>(&self, align: U) -> usize
pub const fn align_offset<U>(self, align: U) -> usize
where
U: ~const Into<usize>,
{
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<U>(&self, align: U) -> bool
pub const fn is_aligned<U>(self, align: U) -> bool
where
U: ~const Into<usize>,
{
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<U>(&self, align: U) -> Self
pub const fn align_down<U>(self, align: U) -> Self
where
U: ~const Into<usize>,
{
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<U>(&self, align: U) -> Self
pub const fn align_up<U>(self, align: U) -> Self
where
U: ~const Into<usize>,
{
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<U>(&self, align: U) -> usize
pub const fn align_offset<U>(self, align: U) -> usize
where
U: ~const Into<usize>,
{
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<U>(&self, align: U) -> bool
pub const fn is_aligned<U>(self, align: U) -> bool
where
U: ~const Into<usize>,
{
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)
}
}
Expand Down

0 comments on commit 706f7d1

Please sign in to comment.