1#[derive(Debug, Clone, Copy, PartialEq)]
11pub struct VirtualMemoryMap {
12 pub pmarea: MemoryArea,
13 pub vmarea: MemoryArea,
14 pub permissions: usize,
15 pub is_shared: bool,
16}
17
18impl VirtualMemoryMap {
19 pub fn new(pmarea: MemoryArea, vmarea: MemoryArea, permissions: usize, is_shared: bool) -> Self {
30 VirtualMemoryMap {
31 pmarea,
32 vmarea,
33 permissions,
34 is_shared,
35 }
36 }
37
38 pub fn get_paddr(&self, vaddr: usize) -> Option<usize> {
47 if self.vmarea.start <= vaddr && vaddr <= self.vmarea.end {
48 Some(self.pmarea.start + (vaddr - self.vmarea.start))
49 } else {
50 None
51 }
52 }
53}
54
55#[derive(Debug, Clone, Copy, PartialEq)]
56pub struct MemoryArea {
57 pub start: usize,
58 pub end: usize,
59}
60
61impl MemoryArea {
62 pub fn new(start: usize, end: usize) -> Self {
64 Self { start, end }
65 }
66
67 pub fn from_ptr(ptr: *const u8, size: usize) -> Self {
69 let start = ptr as usize;
70 let end = if size > 0 { start + size - 1 } else { start };
71 Self { start, end }
72 }
73
74 pub fn size(&self) -> usize {
76 if self.start > self.end {
77 panic!("Invalid memory area: start > end: {:#x} > {:#x}", self.start, self.end);
78 }
79 self.end - self.start + 1
80 }
81
82 pub unsafe fn as_slice(&self) -> &[u8] {
94 unsafe { core::slice::from_raw_parts(self.start as *const u8, self.size()) }
95 }
96
97 pub unsafe fn as_slice_mut(&self) -> &mut [u8] {
109 unsafe { core::slice::from_raw_parts_mut(self.start as *mut u8, self.size()) }
110 }
111}
112
113#[derive(Debug, Clone, Copy)]
114pub enum VirtualMemoryPermission {
115 Read = 0x01,
116 Write = 0x02,
117 Execute = 0x04,
118 User = 0x08,
119}
120
121impl From<usize> for VirtualMemoryPermission {
122 fn from(value: usize) -> Self {
123 match value {
124 0x01 => VirtualMemoryPermission::Read,
125 0x02 => VirtualMemoryPermission::Write,
126 0x04 => VirtualMemoryPermission::Execute,
127 0x08 => VirtualMemoryPermission::User,
128 _ => panic!("Invalid permission value: {}", value),
129 }
130 }
131}
132
133impl VirtualMemoryPermission {
134 pub fn contained_in(&self, permissions: usize) -> bool {
135 permissions & (*self as usize) != 0
136 }
137}
138
139pub enum VirtualMemoryRegion {
140 Text,
141 Data,
142 Bss,
143 Heap,
144 Stack,
145 Guard,
146 Unknown,
147}
148
149impl VirtualMemoryRegion {
150 pub fn default_permissions(&self) -> usize {
151 match self {
152 VirtualMemoryRegion::Text => VirtualMemoryPermission::Read as usize | VirtualMemoryPermission::Execute as usize | VirtualMemoryPermission::User as usize,
153 VirtualMemoryRegion::Data => VirtualMemoryPermission::Read as usize | VirtualMemoryPermission::Write as usize | VirtualMemoryPermission::User as usize,
154 VirtualMemoryRegion::Bss => VirtualMemoryPermission::Read as usize | VirtualMemoryPermission::Write as usize | VirtualMemoryPermission::User as usize,
155 VirtualMemoryRegion::Heap => VirtualMemoryPermission::Read as usize | VirtualMemoryPermission::Write as usize | VirtualMemoryPermission::User as usize,
156 VirtualMemoryRegion::Stack => VirtualMemoryPermission::Read as usize | VirtualMemoryPermission::Write as usize | VirtualMemoryPermission::User as usize,
157 VirtualMemoryRegion::Guard => 0, VirtualMemoryRegion::Unknown => panic!("Unknown memory segment"),
159 }
160 }
161
162 pub fn is_shareable(&self) -> bool {
164 match self {
165 VirtualMemoryRegion::Text => true, VirtualMemoryRegion::Data => false, VirtualMemoryRegion::Bss => false, VirtualMemoryRegion::Heap => false, VirtualMemoryRegion::Stack => false, VirtualMemoryRegion::Guard => true, VirtualMemoryRegion::Unknown => false, }
173 }
174}