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}