ostd/mm/mem_obj.rs
1// SPDX-License-Identifier: MPL-2.0
2
3//! Traits for memory objects.
4
5use alloc::{boxed::Box, rc::Rc, sync::Arc};
6use core::ops::Range;
7
8use super::Paddr;
9use crate::mm::Daddr;
10
11/// Memory objects that have a start physical address.
12pub trait HasPaddr {
13 /// Returns the start physical address of the memory object.
14 fn paddr(&self) -> Paddr;
15}
16
17/// Memory objects that have a mapped address in the device address space.
18pub trait HasDaddr {
19 /// Returns the base address of the mapping in the device address space.
20 fn daddr(&self) -> Daddr;
21}
22
23/// Memory objects that have a length in bytes.
24pub trait HasSize {
25 /// Returns the size of the memory object in bytes.
26 fn size(&self) -> usize;
27}
28
29/// Memory objects that have a physical address range.
30pub trait HasPaddrRange: HasPaddr + HasSize {
31 /// Returns the end physical address of the memory object.
32 fn end_paddr(&self) -> Paddr;
33
34 /// Returns the physical address range of the memory object.
35 fn paddr_range(&self) -> Range<Paddr>;
36}
37
38impl<T: HasPaddr + HasSize> HasPaddrRange for T {
39 fn end_paddr(&self) -> Paddr {
40 self.paddr() + self.size()
41 }
42
43 fn paddr_range(&self) -> Range<Paddr> {
44 self.paddr()..self.end_paddr()
45 }
46}
47
48macro_rules! impl_has_traits_for_ref_type {
49 ($t:ty, $([$trait_name:ident, $fn_name:ident]),*) => {
50 $(
51 impl<T: $trait_name> $trait_name for $t {
52 fn $fn_name(&self) -> usize {
53 (**self).$fn_name()
54 }
55 }
56 )*
57 };
58 ($($t:ty),*) => {
59 $(
60 impl_has_traits_for_ref_type!($t, [HasPaddr, paddr], [HasDaddr, daddr], [HasSize, size]);
61 )*
62 };
63}
64
65impl_has_traits_for_ref_type!(&T, &mut T, Rc<T>, Arc<T>, Box<T>);
66
67/// Memory objects that can be split into smaller parts.
68pub trait Split: Sized + HasSize {
69 /// Splits the memory object into two at the given byte offset from the
70 /// start.
71 ///
72 /// The resulting memory object cannot be empty. So the offset cannot be
73 /// neither zero nor the length of the memory object.
74 ///
75 /// # Panics
76 ///
77 /// The function panics if the offset is out of bounds, at either ends, or
78 /// not base-page-aligned.
79 fn split(self, offset: usize) -> (Self, Self);
80}