nvme/hosted/memory/
mod.rs1use crate::ds::{cmd::PrpListOrBuffer, queue::subentry::Dptr, Address};
2
3pub struct VirtualRegion<P: PhysicalPageCollection> {
4 virt: *mut u8,
5 _cache_type: CacheType,
6 phys_page_list: P,
7 len: usize,
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
11pub enum PrpMode {
12 Single,
13 Double,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
17pub enum DptrMode {
18 Prp(PrpMode),
19 Sgl,
20}
21
22pub trait PhysicalPageCollection {
23 type DmaType;
24 fn get_prp_list_or_buffer(
25 &mut self,
26 mode: PrpMode,
27 dma: Self::DmaType,
28 ) -> Option<PrpListOrBuffer>;
29
30 fn get_dptr(&mut self, mode: DptrMode, dma: Self::DmaType) -> Option<Dptr> {
31 if let DptrMode::Prp(prp_mode) = mode {
32 let prp = self.get_prp_list_or_buffer(prp_mode, dma)?;
33 match prp {
34 PrpListOrBuffer::PrpList(address) => Some(Dptr::Prp(address, 0)),
35 PrpListOrBuffer::Buffer(address) => Some(Dptr::Prp(address, 0)),
36 PrpListOrBuffer::PrpFirstAndList(first, list) => Some(Dptr::Prp(first, list)),
37 }
38 } else {
39 todo!()
40 }
41 }
42}
43
44pub enum CacheType {
45 WriteBack,
46 WriteThrough,
47 Uncacheable,
48}
49
50impl PrpListOrBuffer {
51 pub fn address(&self) -> Address {
52 match self {
53 PrpListOrBuffer::PrpList(a) => *a,
54 PrpListOrBuffer::PrpFirstAndList(_, _) => panic!("cannot get single address"),
55 PrpListOrBuffer::Buffer(a) => *a,
56 }
57 }
58
59 pub fn is_list(&self) -> bool {
60 match self {
61 PrpListOrBuffer::PrpList(_) => true,
62 PrpListOrBuffer::PrpFirstAndList(_, _) => true,
63 PrpListOrBuffer::Buffer(_) => false,
64 }
65 }
66}
67
68impl<P: PhysicalPageCollection> VirtualRegion<P> {
69 pub fn len(&self) -> usize {
70 self.len
71 }
72
73 pub unsafe fn new(
74 virt: *mut u8,
75 len: usize,
76 _cache_type: CacheType,
77 phys_page_list: P,
78 ) -> Self {
79 Self {
80 len,
81 virt,
82 _cache_type,
83 phys_page_list,
84 }
85 }
86
87 pub fn base<T>(&self) -> *const T {
88 self.virt as *const T
89 }
90
91 pub fn base_mut<T>(&mut self) -> *mut T {
92 self.virt as *mut T
93 }
94
95 pub fn get_prp_list_or_buffer<D>(
96 &mut self,
97 mode: PrpMode,
98 dma: P::DmaType,
99 ) -> Option<PrpListOrBuffer> {
100 self.phys_page_list.get_prp_list_or_buffer(mode, dma)
101 }
102
103 pub fn get_dptr(&mut self, mode: DptrMode, dma: P::DmaType) -> Option<Dptr> {
104 self.phys_page_list.get_dptr(mode, dma)
105 }
106}