axmm/
page_iter_wrapper.rs

1//! Memory Page Iterator Wrapper Module
2//!
3//! Provides a unified iteration interface across different page sizes,
4//! supporting address iteration for 4K, 2M, and 1G page sizes.
5//! The design is inspired by the Iterator Wrapper pattern,
6//! using an enum to unify the behavior of iterators for different page sizes.
7
8use axhal::mem::VirtAddr;
9use axhal::paging::PageSize;
10use memory_addr::PageIter;
11
12/// 4K page size constant (4,096 bytes) and iterator type alias
13pub use memory_addr::{PAGE_SIZE_4K, PageIter4K};
14
15/// 2MB page size constant (2,097,152 bytes)
16pub const PAGE_SIZE_2M: usize = 0x20_0000;
17
18/// 2MB page iterator type alias
19///
20/// Wraps the `PageIter` struct with a fixed page size of `PAGE_SIZE_2M`
21pub type PageIter2M<A> = PageIter<PAGE_SIZE_2M, A>;
22
23/// 1GB page size constant (1,073,741,824 bytes)
24pub const PAGE_SIZE_1G: usize = 0x4000_0000;
25
26/// 1GB page iterator type alias
27///
28/// Wraps the `PageIter` struct with a fixed page size of `PAGE_SIZE_1G`
29pub type PageIter1G<A> = PageIter<PAGE_SIZE_1G, A>;
30
31/// Page Iterator Wrapper Enum
32///
33/// Unifies the iterator interfaces for different page sizes, enabling transparent
34/// access to address iteration.
35/// The design follows the Iterator Wrapper pattern, eliminating type differences
36/// between iterators of varying page sizes.
37pub enum PageIterWrapper {
38    /// 4K page iterator variant
39    Size4K(PageIter4K<VirtAddr>),
40    /// 2M page iterator variant
41    Size2M(PageIter2M<VirtAddr>),
42    /// 1G page iterator variant
43    Size1G(PageIter1G<VirtAddr>),
44}
45
46impl PageIterWrapper {
47    /// Creates an iterator wrapper instance for the specified page size
48    ///
49    /// # Parameters
50    /// - `start`: Starting virtual address (inclusive), which must be aligned to the `page_size`
51    /// - `end`: Ending virtual address (exclusive), which must also be aligned to the `page_size`
52    /// - `page_size`: Enum type specifying the page size
53    ///
54    /// # Returns
55    /// Returns an `Option` wrapping the iterator instance. Returns `None` if the page size is unsupported.
56    ///
57    /// # Example
58    /// ```rust
59    /// use axmm::page_iter_wrapper::PageIterWrapper;
60    /// use axhal::paging::PageSize;
61    /// use axhal::mem::VirtAddr;
62    /// let start_addr = VirtAddr::from(0x1000);
63    /// let end_addr = VirtAddr::from(0x3000);
64    /// let iter = PageIterWrapper::new(start_addr, end_addr, PageSize::Size4K);
65    /// ```    
66    pub fn new(start: VirtAddr, end: VirtAddr, page_size: PageSize) -> Option<Self> {
67        match page_size {
68            PageSize::Size4K => PageIter4K::<VirtAddr>::new(start, end).map(Self::Size4K),
69            PageSize::Size2M => PageIter2M::<VirtAddr>::new(start, end).map(Self::Size2M),
70            PageSize::Size1G => PageIter1G::<VirtAddr>::new(start, end).map(Self::Size1G),
71        }
72    }
73}
74
75/// Iterator trait implementation
76///
77/// Unifies address iteration behavior for all three page sizes,
78/// providing a transparent external access interface.
79/// The implementation follows the paginated iterator design pattern,
80/// using an enum to dispatch calls to the underlying iterators.
81impl Iterator for PageIterWrapper {
82    type Item = VirtAddr;
83
84    /// Retrieves the next virtual address
85    ///
86    /// # Returns
87    /// Returns an `Option` wrapping the virtual address. Returns `None` when the iteration is complete.
88    ///
89    /// # Implementation Details
90    /// Based on the current enum variant, the corresponding underlying iterator is called.
91    /// The original behavior of each page size iterator is preserved.
92    fn next(&mut self) -> Option<Self::Item> {
93        match self {
94            Self::Size4K(iter) => iter.next(),
95            Self::Size2M(iter) => iter.next(),
96            Self::Size1G(iter) => iter.next(),
97        }
98    }
99}