Skip to main content

sbi_spec/binary/
physical_slice.rs

1use core::marker::PhantomData;
2
3/// Physical slice wrapper with type annotation.
4///
5/// This struct wraps slices in RISC-V physical memory by low and high part of the
6/// physical base address as well as its length. It is usually used by SBI extensions
7/// as parameter types to pass base address and length parameters on physical memory
8/// other than a virtual one.
9///
10/// Generic parameter `P` represents a hint of how this physical slice would be used.
11/// For example, `Physical<&[u8]>` represents an immutable reference to physical byte slice,
12/// while `Physical<&mut [u8]>` represents a mutable one.
13///
14/// An SBI implementation should load or store memory using both `phys_addr_lo` and
15/// `phys_addr_hi` combined as base address. A supervisor program (kernels etc.)
16/// should provide continuous physical memory, wrapping its reference using this structure
17/// before passing into SBI runtime.
18#[derive(Clone, Copy)]
19pub struct Physical<P> {
20    num_bytes: usize,
21    phys_addr_lo: usize,
22    phys_addr_hi: usize,
23    _marker: PhantomData<P>,
24}
25
26impl<P> Physical<P> {
27    /// Create a physical memory slice by length and physical address.
28    #[inline]
29    pub const fn new(num_bytes: usize, phys_addr_lo: usize, phys_addr_hi: usize) -> Self {
30        Self {
31            num_bytes,
32            phys_addr_lo,
33            phys_addr_hi,
34            _marker: core::marker::PhantomData,
35        }
36    }
37
38    /// Returns length of the physical memory slice.
39    #[inline]
40    pub const fn num_bytes(&self) -> usize {
41        self.num_bytes
42    }
43
44    /// Returns low-part base address of physical memory slice.
45    #[inline]
46    pub const fn phys_addr_lo(&self) -> usize {
47        self.phys_addr_lo
48    }
49
50    /// Returns high-part base address of physical memory slice.
51    #[inline]
52    pub const fn phys_addr_hi(&self) -> usize {
53        self.phys_addr_hi
54    }
55}