1#![cfg_attr(not(test), no_std)]
2#![doc = include_str!("../README.md")]
3
4#[cfg(test)]
5extern crate alloc;
6
7mod addr;
8mod iter;
9mod range;
10
11pub use self::{
12 addr::{MemoryAddr, PhysAddr, VirtAddr},
13 iter::{DynPageIter, PageIter},
14 range::{AddrRange, PhysAddrRange, VirtAddrRange},
15};
16
17pub const PAGE_SIZE_4K: usize = 0x1000;
19
20pub const PAGE_SIZE_2M: usize = 0x20_0000;
22
23pub const PAGE_SIZE_1G: usize = 0x4000_0000;
25
26pub type PageIter4K<A> = PageIter<PAGE_SIZE_4K, A>;
28
29pub type PageIter2M<A> = PageIter<PAGE_SIZE_2M, A>;
31
32pub type PageIter1G<A> = PageIter<PAGE_SIZE_1G, A>;
34
35#[inline]
41pub const fn align_down(addr: usize, align: usize) -> usize {
42 addr & !(align - 1)
43}
44
45#[inline]
51pub const fn align_up(addr: usize, align: usize) -> usize {
52 (addr + align - 1) & !(align - 1)
53}
54
55#[inline]
59pub const fn align_offset(addr: usize, align: usize) -> usize {
60 addr & (align - 1)
61}
62
63#[inline]
67pub const fn is_aligned(addr: usize, align: usize) -> bool {
68 align_offset(addr, align) == 0
69}
70
71#[inline]
73pub const fn align_down_4k(addr: usize) -> usize {
74 align_down(addr, PAGE_SIZE_4K)
75}
76
77#[inline]
79pub const fn align_up_4k(addr: usize) -> usize {
80 align_up(addr, PAGE_SIZE_4K)
81}
82
83#[inline]
85pub const fn align_offset_4k(addr: usize) -> usize {
86 align_offset(addr, PAGE_SIZE_4K)
87}
88
89#[inline]
91pub const fn is_aligned_4k(addr: usize) -> bool {
92 is_aligned(addr, PAGE_SIZE_4K)
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn test_align() {
101 assert_eq!(align_down(0x12345678, 0x1000), 0x12345000);
102 assert_eq!(align_up(0x12345678, 0x1000), 0x12346000);
103 assert_eq!(align_offset(0x12345678, 0x1000), 0x678);
104 assert!(is_aligned(0x12345000, 0x1000));
105 assert!(!is_aligned(0x12345678, 0x1000));
106
107 assert_eq!(align_down_4k(0x12345678), 0x12345000);
108 assert_eq!(align_up_4k(0x12345678), 0x12346000);
109 assert_eq!(align_offset_4k(0x12345678), 0x678);
110 assert!(is_aligned_4k(0x12345000));
111 assert!(!is_aligned_4k(0x12345678));
112 }
113
114 #[test]
115 fn page_size_constants_and_alignment_boundaries_hold() {
116 assert_eq!(PAGE_SIZE_4K, 4096);
117 assert_eq!(PAGE_SIZE_2M, 2_097_152);
118 assert_eq!(PAGE_SIZE_1G, 1_073_741_824);
119
120 assert_eq!(align_down(0, 4096), 0);
121 assert_eq!(align_up(0, 4096), 0);
122 assert_eq!(align_down(4096, 4096), 4096);
123 assert_eq!(align_up(4096, 4096), 4096);
124 assert_eq!(align_down(4097, 4096), 4096);
125 assert_eq!(align_up(4097, 4096), 8192);
126 }
127
128 #[test]
129 fn align_4k_helpers_cover_unaligned_addresses() {
130 assert_eq!(align_down_4k(0x12345), 0x12000);
131 assert_eq!(align_up_4k(0x12345), 0x13000);
132 assert_eq!(align_offset_4k(0x12345), 0x345);
133 assert!(is_aligned_4k(0x12000));
134 assert!(!is_aligned_4k(0x12001));
135 }
136}