os/mm/address/
address.rs

1//! 地址抽象模块
2//!
3//! 此模块定义了表示内存地址的核心 Trait ([Address]),以及具体的
4//! 地址类型 ([Paddr] 物理地址, [Vaddr] 虚拟地址),并提供了地址算术、
5//! 对齐操作以及地址范围 ([AddressRange]) 的支持。
6
7use crate::mm::address::operations::{AlignOps, CalcOps, UsizeConvert};
8use core::mem::size_of;
9use core::ops::Range;
10
11/// [Address] Trait
12/// ---------------------
13/// 表示一个内存地址的 Trait。所有地址类型必须实现此 Trait。
14/// 它组合了算术运算 ([CalcOps])、对齐操作 ([AlignOps]) 和 usize 转换 ([UsizeConvert])。
15pub trait Address:
16    CalcOps + AlignOps + UsizeConvert + Copy + Clone + PartialEq + PartialOrd + Eq + Ord
17{
18    /// 检查地址是否为空 (即零)。
19    fn is_null(self) -> bool {
20        self.as_usize() == 0
21    }
22
23    /// 返回一个空地址 (零地址)。
24    fn null() -> Self {
25        Self::from_usize(0)
26    }
27
28    /// 获取地址在当前页内的偏移量。
29    fn page_offset(self) -> usize {
30        // 使用位掩码 (PAGE_SIZE - 1) 快速计算页内偏移
31        self.as_usize() & (crate::config::PAGE_SIZE - 1)
32    }
33
34    /// 计算两个地址之间的字节差值。
35    fn addr_diff(self, other: Self) -> isize {
36        self.as_usize() as isize - other.as_usize() as isize
37    }
38
39    /// 将地址增加 `T` 类型的大小。
40    ///
41    /// # 泛型
42    /// * `T`: 要增加其大小的类型。
43    fn add<T>(self) -> Self {
44        self.add_by(size_of::<T>())
45    }
46
47    /// 将地址增加 `n` 个 `T` 类型元素的大小。
48    ///
49    /// # 参数
50    /// * `n`: 元素个数。
51    fn add_n<T>(self, n: usize) -> Self {
52        self.add_by(size_of::<T>() * n)
53    }
54
55    /// 将地址增加指定的字节偏移量。
56    fn add_by(self, offset: usize) -> Self {
57        Self::from_usize(self.as_usize() + offset)
58    }
59
60    /// 将地址减去 `Self` 类型的大小 (通常是 `size_of::<usize>`)。
61    fn sub(self) -> Self {
62        self.sub_by(size_of::<Self>())
63    }
64
65    /// 将地址减去 `n` 个 `Self` 类型元素的大小。
66    fn sub_n(self, n: usize) -> Self {
67        self.sub_by(size_of::<Self>() * n)
68    }
69
70    /// 将地址减去指定的字节偏移量。
71    fn sub_by(self, offset: usize) -> Self {
72        Self::from_usize(self.as_usize() - offset)
73    }
74
75    /// 将地址增加 `Self` 类型的大小 (原地修改)。
76    fn step(&mut self) {
77        self.step_by(size_of::<Self>())
78    }
79
80    /// 将地址增加 `n` 个 `Self` 类型元素的大小 (原地修改)。
81    fn step_n(&mut self, n: usize) {
82        self.step_by(size_of::<Self>() * n)
83    }
84
85    /// 将地址减去 `Self` 类型的大小 (原地修改)。
86    fn step_back(&mut self) {
87        self.step_back_by(size_of::<Self>())
88    }
89
90    /// 将地址减去 `n` 个 `Self` 类型元素的大小 (原地修改)。
91    fn step_back_n(&mut self, n: usize) {
92        self.step_back_by(size_of::<Self>() * n)
93    }
94
95    /// 将地址增加给定的字节偏移量 (原地修改)。
96    fn step_by(&mut self, offset: usize) {
97        *self = self.add_by(offset);
98    }
99
100    /// 将地址减去给定的字节偏移量 (原地修改)。
101    fn step_back_by(&mut self, offset: usize) {
102        *self = self.sub_by(offset);
103    }
104}
105
106/// `impl_address!` 宏
107/// ---------------------
108/// 快速为地址类型实现所有必需的 Trait: [UsizeConvert], [CalcOps], [AlignOps], [Address]。
109///
110/// 注意:这里使用 `transmute` 在地址类型 (例如 `Paddr(*const ())`) 和 `usize` 之间进行
111/// 零开销转换,这是操作地址类型时的标准做法。
112#[macro_export]
113macro_rules! impl_address {
114    ($type:ty) => {
115        impl $crate::mm::address::operations::UsizeConvert for $type {
116            /// 将地址类型转换为其原始的 `usize` 值。
117            fn as_usize(&self) -> usize {
118                // SAFETY: 地址类型 (Paddr/Vaddr) 是 transparent 的,并且保证和 usize 大小相同。
119                unsafe { core::mem::transmute::<Self, usize>(*self) }
120            }
121
122            /// 从 `usize` 值创建地址类型。
123            fn from_usize(value: usize) -> Self {
124                // SAFETY: 这是一个零开销的转换,将原始值转换为地址类型。
125                unsafe { core::mem::transmute::<usize, Self>(value) }
126            }
127        }
128
129        $crate::impl_calc_ops!($type);
130        impl $crate::mm::address::operations::AlignOps for $type {}
131
132        impl $crate::mm::address::address::Address for $type {}
133
134        // 地址类型通常需要在多线程环境下传递和共享
135        unsafe impl Sync for $type {}
136        unsafe impl Send for $type {}
137    };
138}
139
140/// [ConvertablePaddr] Trait
141/// ---------------------
142/// 物理地址转换为虚拟地址的能力。
143pub trait ConvertablePaddr {
144    /// 检查地址是否是有效的物理地址。
145    fn is_valid_paddr(&self) -> bool;
146    /// 将物理地址转换为虚拟地址。
147    fn to_vaddr(&self) -> Vaddr;
148}
149
150/// [Paddr] (Physical Address)
151/// ---------------------
152/// 物理内存地址,对应于内存芯片上的实际位置。
153#[repr(transparent)]
154#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
155pub struct Paddr(pub *const ());
156impl_address!(Paddr);
157
158impl ConvertablePaddr for Paddr {
159    fn is_valid_paddr(&self) -> bool {
160        // 注意: 实际实现依赖于具体的架构函数 `vaddr_to_paddr`,
161        // 这里的逻辑通常需要检查地址是否在物理内存范围内。
162        self.as_usize() == unsafe { crate::arch::mm::vaddr_to_paddr(self.as_usize()) }
163    }
164
165    fn to_vaddr(&self) -> Vaddr {
166        // 依赖于架构特定的映射函数 (例如:线性映射或固定偏移)
167        Vaddr::from_usize(crate::arch::mm::paddr_to_vaddr(self.as_usize()))
168    }
169}
170
171/// [ConvertableVaddr] Trait
172/// ---------------------
173/// 虚拟地址转换为物理地址的能力。
174pub trait ConvertableVaddr {
175    /// 检查地址是否是有效的虚拟地址。
176    fn is_valid_vaddr(&self) -> bool;
177    /// 将虚拟地址转换为物理地址。
178    fn to_paddr(&self) -> Paddr;
179}
180
181/// [Vaddr] (Virtual Address)
182/// ---------------------
183/// 虚拟内存地址,对应于进程或内核的页表映射空间中的位置。
184#[repr(transparent)]
185#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
186pub struct Vaddr(pub *const ());
187impl_address!(Vaddr);
188
189impl ConvertableVaddr for Vaddr {
190    fn is_valid_vaddr(&self) -> bool {
191        // 注意: 实际实现通常涉及查询页表来确定映射关系。
192        self.as_usize() == crate::arch::mm::paddr_to_vaddr(self.as_usize())
193    }
194
195    fn to_paddr(&self) -> Paddr {
196        // 依赖于架构特定的反向映射函数 (查询页表或固定偏移)
197        Paddr::from_usize(unsafe { crate::arch::mm::vaddr_to_paddr(self.as_usize()) })
198    }
199}
200
201impl Vaddr {
202    /// 从一个不可变引用创建虚拟地址。
203    pub fn from_ref<T>(r: &T) -> Self {
204        Self::from_ptr(r as *const T)
205    }
206
207    /// 从一个常量指针创建虚拟地址。
208    pub fn from_ptr<T>(p: *const T) -> Self {
209        Self::from_usize(p as usize)
210    }
211
212    /// 将虚拟地址转换为一个不可变引用。
213    ///
214    /// # Safety (不安全函数)
215    /// 调用者必须确保:
216    /// 1. 地址指向的内存是 **有效** 的且 **已初始化** 的 `T` 类型数据。
217    /// 2. 内存在引用的生命周期内不会被修改 (即引用是不可变的)。
218    /// 3. 地址已经正确映射,且对齐满足 `T` 的要求。
219    pub unsafe fn as_ref<T>(&self) -> &T {
220        unsafe { &*(self.as_usize() as *const T) }
221    }
222
223    /// 将虚拟地址转换为一个可变引用。
224    ///
225    /// # Safety (不安全函数)
226    /// 调用者必须确保:
227    /// 1. 地址指向的内存是 **有效** 的且 **已初始化** 的 `T` 类型数据。
228    /// 2. 内存是 **独占** 的 (没有其他活跃的引用或指针指向它)。
229    /// 3. 地址已经正确映射,且对齐满足 `T` 的要求。
230    pub unsafe fn as_mut<T>(&mut self) -> &mut T {
231        unsafe { &mut *(self.as_usize() as *mut T) }
232    }
233
234    /// 将虚拟地址转换为一个常量指针。
235    pub fn as_ptr<T>(&self) -> *const T {
236        self.as_usize() as *const T
237    }
238
239    /// 将虚拟地址转换为一个可变指针。
240    ///
241    /// # Safety (不安全函数)
242    /// 调用者必须确保地址在被解引用时是有效的。
243    pub unsafe fn as_mut_ptr<T>(&mut self) -> *mut T {
244        self.as_usize() as *mut T
245    }
246}
247
248/// [AddressRange]
249/// ---------------------
250/// 泛型地址范围结构,表示一个半开半闭的区间 `[start, end)`。
251#[repr(C)]
252#[derive(Clone, Copy, Debug, PartialEq, Eq)]
253pub struct AddressRange<T>
254where
255    T: Address,
256{
257    /// 范围的起始地址 (包含)。
258    start: T,
259    /// 范围的结束地址 (不包含)。
260    end: T,
261}
262
263impl<T> AddressRange<T>
264where
265    T: Address,
266{
267    /// 创建一个新的地址范围。
268    pub fn new(start: T, end: T) -> Self {
269        Self { start, end }
270    }
271
272    /// 从 Rust 标准库的 `Range<T>` 创建一个地址范围。
273    pub fn from_range(range: Range<T>) -> Self {
274        Self {
275            start: range.start,
276            end: range.end,
277        }
278    }
279
280    /// 从起始地址和长度 (字节数) 创建一个地址范围。
281    pub fn from_start_len(start: T, len: usize) -> Self {
282        Self {
283            start,
284            end: T::from_usize(start.as_usize() + len),
285        }
286    }
287
288    /// 从地址切片中创建地址范围 (使用第一个和最后一个地址)。
289    ///
290    /// # 返回
291    /// 如果切片长度小于 2,返回 `None`。
292    pub fn from_slices(slices: &[T]) -> Option<Self> {
293        if slices.len() < 2 {
294            return None;
295        }
296        // 注意: 这里假设切片中的地址是连续的,并计算到最后一个元素的结束地址。
297        //      实际中可能需要更复杂的逻辑来确定范围。
298        Some(Self {
299            start: slices[0],
300            end: slices[slices.len() - 1],
301        })
302    }
303
304    /// 获取起始地址。
305    pub fn start(&self) -> T {
306        self.start
307    }
308
309    /// 获取结束地址 (不包含)。
310    pub fn end(&self) -> T {
311        self.end
312    }
313
314    /// 获取范围的字节长度。
315    pub fn len(&self) -> usize {
316        debug_assert!(self.end.as_usize() >= self.start.as_usize());
317        self.end.as_usize() - self.start.as_usize()
318    }
319
320    /// 检查范围是否为空 (即 start == end)。
321    pub fn empty(&self) -> bool {
322        self.start == self.end
323    }
324
325    /// 检查范围是否包含给定的地址。
326    pub fn contains(&self, addr: T) -> bool {
327        addr >= self.start && addr < self.end
328    }
329
330    /// 检查范围是否包含另一个范围。
331    pub fn contains_range(&self, other: &Self) -> bool {
332        other.start >= self.start && other.end <= self.end
333    }
334
335    /// 检查此范围是否包含在另一个范围中。
336    pub fn contains_in(&self, other: &Self) -> bool {
337        self.start >= other.start && self.end <= other.end
338    }
339
340    /// 检查两个范围是否相交 (有共同的字节)。
341    pub fn intersects(&self, other: &Self) -> bool {
342        self.start < other.end && other.start < self.end
343    }
344
345    /// 检查两个范围是否邻接 (一个的结束地址等于另一个的起始地址)。
346    pub fn adjacent(&self, other: &Self) -> bool {
347        self.end == other.start || other.end == self.start
348    }
349
350    /// 获取两个范围的交集。
351    ///
352    /// # 返回
353    /// 如果不相交,返回 `None`。
354    pub fn intersection(&self, other: &Self) -> Option<Self> {
355        if !self.intersects(other) {
356            return None;
357        }
358        let start = core::cmp::max(self.start, other.start);
359        let end = core::cmp::min(self.end, other.end);
360        Some(Self { start, end })
361    }
362
363    /// 获取两个范围的并集。
364    ///
365    /// # 返回
366    /// 如果既不相交也不邻接,返回 `None`。
367    pub fn union(&self, other: &Self) -> Option<Self> {
368        if !self.intersects(other) && !self.adjacent(other) {
369            return None;
370        }
371        let start = core::cmp::min(self.start, other.start);
372        let end = core::cmp::max(self.end, other.end);
373        Some(Self { start, end })
374    }
375
376    /// 获取范围的迭代器。
377    pub fn iter(&self) -> AddressRangeIterator<T> {
378        AddressRangeIterator {
379            range: *self,
380            current: self.start,
381        }
382    }
383}
384
385impl<T> IntoIterator for AddressRange<T>
386where
387    T: Address,
388{
389    type Item = T;
390    type IntoIter = AddressRangeIterator<T>;
391
392    fn into_iter(self) -> Self::IntoIter {
393        self.iter()
394    }
395}
396
397/// [AddressRangeIterator]
398/// ---------------------
399/// 地址范围的迭代器,每次步进 `size_of::<T>()` 字节。
400pub struct AddressRangeIterator<T>
401where
402    T: Address,
403{
404    range: AddressRange<T>,
405    current: T,
406}
407
408impl<T> Iterator for AddressRangeIterator<T>
409where
410    T: Address,
411{
412    type Item = T;
413
414    fn next(&mut self) -> Option<Self::Item> {
415        if self.current >= self.range.end {
416            return None;
417        }
418        let addr = self.current;
419        self.current.step(); // 步进 Self 类型的大小
420        Some(addr)
421    }
422}
423
424/// 物理地址范围的类型别名
425pub type PaddrRange = AddressRange<Paddr>;
426
427/// 虚拟地址范围的类型别名
428pub type VaddrRange = AddressRange<Vaddr>;
429
430#[cfg(test)]
431mod address_basic_tests {
432    use super::*;
433    // 假设 arch 模块提供了 paddr_to_vaddr 的桩实现
434    use crate::arch::mm::paddr_to_vaddr;
435    use crate::{kassert, test_case};
436
437    // 1.1 Paddr/Vaddr 创建和转换测试
438    test_case!(test_address_roundtrip, {
439        let test_values = [0x0, 0x1000, 0x8000_0000, 0x8000_1234];
440
441        for &val in &test_values {
442            let paddr = Paddr::from_usize(val);
443            kassert!(paddr.as_usize() == val);
444
445            let vaddr = Vaddr::from_usize(val);
446            kassert!(vaddr.as_usize() == val);
447        }
448    });
449
450    // 1.2 空地址测试
451    test_case!(test_null_address, {
452        let paddr = Paddr::null();
453        kassert!(paddr.is_null());
454        kassert!(paddr.as_usize() == 0);
455    });
456
457    // 1.3 页内偏移测试 (假设 PAGE_SIZE = 0x1000)
458    test_case!(test_page_offset, {
459        let cases = [(0x8000_0000, 0), (0x8000_0123, 0x123), (0x8000_0FFF, 0xFFF)];
460        for &(addr, expected) in &cases {
461            // Vaddr 和 Paddr 的行为应该相同
462            kassert!(Paddr::from_usize(addr).page_offset() == expected);
463            kassert!(Vaddr::from_usize(addr).page_offset() == expected);
464        }
465    });
466
467    // 1.4 Paddr ↔ Vaddr 转换测试 (依赖于 arch/mm 桩实现)
468    test_case!(test_paddr_vaddr_conversion, {
469        let paddrs = [0x8000_0000, 0x8000_1000, 0x8020_0000];
470
471        for &paddr_val in &paddrs {
472            let paddr = Paddr::from_usize(paddr_val);
473            let vaddr = paddr.to_vaddr();
474            let back = vaddr.to_paddr();
475            kassert!(back.as_usize() == paddr_val);
476            kassert!(vaddr.as_usize() == paddr_to_vaddr(paddr_val));
477        }
478    });
479
480    // 1.5 地址比较测试
481    test_case!(test_address_comparison, {
482        let a1 = Paddr::from_usize(0x8000_0000);
483        let a2 = Paddr::from_usize(0x8000_0000);
484        let a3 = Paddr::from_usize(0x8000_1000);
485
486        kassert!(a1 == a2);
487        kassert!(a1 < a3);
488        kassert!(a3 > a1);
489    });
490
491    // 1.6 地址算术和步进测试
492    test_case!(test_address_arithmetic, {
493        let start = Paddr::from_usize(0x1000);
494
495        // add_by
496        kassert!(start.add_by(0x123).as_usize() == 0x1123);
497
498        // add<u32> (size_of::<u32>() == 4)
499        kassert!(start.add::<u32>().as_usize() == 0x1004);
500
501        // add_n<u16> (size_of::<u16>() * 3 == 6)
502        kassert!(start.add_n::<u16>(3).as_usize() == 0x1006);
503
504        // step (Paddr::size_of() == size_of::<usize>())
505        let mut p = start;
506        p.step();
507        kassert!(p.as_usize() == start.as_usize() + size_of::<Paddr>());
508
509        // step_back_by
510        let mut p = Paddr::from_usize(0x2000);
511        p.step_back_by(0x10);
512        kassert!(p.as_usize() == 0x1FF0);
513    });
514}