xref: /DragonOS/kernel/src/mm/memblock.rs (revision 45626c859f95054b76d8b59afcbd24c6b235026f)
1*45626c85SLoGin use system_error::SystemError;
2*45626c85SLoGin 
3*45626c85SLoGin use crate::libs::spinlock::{SpinLock, SpinLockGuard};
4*45626c85SLoGin 
5*45626c85SLoGin use super::{PhysAddr, PhysMemoryArea};
6*45626c85SLoGin 
7*45626c85SLoGin pub const INITIAL_MEMORY_REGIONS_NUM: usize = 128;
8*45626c85SLoGin 
9*45626c85SLoGin /// 初始内存区域
10*45626c85SLoGin static MEM_BLOCK_MANAGER: MemBlockManager = MemBlockManager::new();
11*45626c85SLoGin 
12*45626c85SLoGin #[inline(always)]
13*45626c85SLoGin pub fn mem_block_manager() -> &'static MemBlockManager {
14*45626c85SLoGin     &MEM_BLOCK_MANAGER
15*45626c85SLoGin }
16*45626c85SLoGin 
17*45626c85SLoGin /// 内存区域管理器
18*45626c85SLoGin #[derive(Debug)]
19*45626c85SLoGin pub struct MemBlockManager {
20*45626c85SLoGin     inner: SpinLock<InnerMemBlockManager>,
21*45626c85SLoGin }
22*45626c85SLoGin 
23*45626c85SLoGin #[derive(Debug)]
24*45626c85SLoGin pub struct InnerMemBlockManager {
25*45626c85SLoGin     /// 初始内存区域
26*45626c85SLoGin     ///
27*45626c85SLoGin     /// 用于记录内核启动时的内存布局, 这些区域保持升序、不重叠
28*45626c85SLoGin     initial_memory_regions: [PhysMemoryArea; INITIAL_MEMORY_REGIONS_NUM],
29*45626c85SLoGin     initial_memory_regions_num: usize,
30*45626c85SLoGin }
31*45626c85SLoGin 
32*45626c85SLoGin impl MemBlockManager {
33*45626c85SLoGin     #[allow(dead_code)]
34*45626c85SLoGin     pub const MIN_MEMBLOCK_ADDR: PhysAddr = PhysAddr::new(0);
35*45626c85SLoGin     #[allow(dead_code)]
36*45626c85SLoGin     pub const MAX_MEMBLOCK_ADDR: PhysAddr = PhysAddr::new(usize::MAX);
37*45626c85SLoGin     const fn new() -> Self {
38*45626c85SLoGin         Self {
39*45626c85SLoGin             inner: SpinLock::new(InnerMemBlockManager {
40*45626c85SLoGin                 initial_memory_regions: [PhysMemoryArea::DEFAULT; INITIAL_MEMORY_REGIONS_NUM],
41*45626c85SLoGin                 initial_memory_regions_num: 0,
42*45626c85SLoGin             }),
43*45626c85SLoGin         }
44*45626c85SLoGin     }
45*45626c85SLoGin 
46*45626c85SLoGin     /// 添加内存区域
47*45626c85SLoGin     ///
48*45626c85SLoGin     /// 如果添加的区域与已有区域有重叠,会将重叠的区域合并
49*45626c85SLoGin     #[allow(dead_code)]
50*45626c85SLoGin     pub fn add_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
51*45626c85SLoGin         if size == 0 {
52*45626c85SLoGin             return Ok(());
53*45626c85SLoGin         }
54*45626c85SLoGin         let mut inner = self.inner.lock();
55*45626c85SLoGin         if inner.initial_memory_regions_num >= INITIAL_MEMORY_REGIONS_NUM {
56*45626c85SLoGin             panic!("Too many memory regions!");
57*45626c85SLoGin         }
58*45626c85SLoGin 
59*45626c85SLoGin         let block = PhysMemoryArea::new(base, size);
60*45626c85SLoGin         // 特判第一个区域
61*45626c85SLoGin         if inner.initial_memory_regions_num == 0 {
62*45626c85SLoGin             inner.initial_memory_regions[0] = block;
63*45626c85SLoGin             inner.initial_memory_regions_num += 1;
64*45626c85SLoGin             return Ok(());
65*45626c85SLoGin         }
66*45626c85SLoGin 
67*45626c85SLoGin         // 先计算需要添加的区域数量
68*45626c85SLoGin         let blocks_to_add = self
69*45626c85SLoGin             .do_add_block(&mut inner, block, false)
70*45626c85SLoGin             .expect("Failed to count blocks to add!");
71*45626c85SLoGin 
72*45626c85SLoGin         if inner.initial_memory_regions_num + blocks_to_add > INITIAL_MEMORY_REGIONS_NUM {
73*45626c85SLoGin             kerror!("Too many memory regions!");
74*45626c85SLoGin             return Err(SystemError::ENOMEM);
75*45626c85SLoGin         }
76*45626c85SLoGin 
77*45626c85SLoGin         // 然后添加区域
78*45626c85SLoGin         self.do_add_block(&mut inner, block, true)
79*45626c85SLoGin             .expect("Failed to add block!");
80*45626c85SLoGin 
81*45626c85SLoGin         return Ok(());
82*45626c85SLoGin     }
83*45626c85SLoGin 
84*45626c85SLoGin     fn do_add_block(
85*45626c85SLoGin         &self,
86*45626c85SLoGin         inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
87*45626c85SLoGin         block: PhysMemoryArea,
88*45626c85SLoGin         insert: bool,
89*45626c85SLoGin     ) -> Result<usize, SystemError> {
90*45626c85SLoGin         let mut base = block.base;
91*45626c85SLoGin         let end = block.base + block.size;
92*45626c85SLoGin         let mut i = 0;
93*45626c85SLoGin         let mut start_index = -1;
94*45626c85SLoGin         let mut end_index = -1;
95*45626c85SLoGin 
96*45626c85SLoGin         let mut num_to_add = 0;
97*45626c85SLoGin 
98*45626c85SLoGin         while i < inner.initial_memory_regions_num {
99*45626c85SLoGin             let range_base = inner.initial_memory_regions[i].base;
100*45626c85SLoGin             let range_end =
101*45626c85SLoGin                 inner.initial_memory_regions[i].base + inner.initial_memory_regions[i].size;
102*45626c85SLoGin 
103*45626c85SLoGin             if range_base >= end {
104*45626c85SLoGin                 break;
105*45626c85SLoGin             }
106*45626c85SLoGin             if range_end <= base {
107*45626c85SLoGin                 i += 1;
108*45626c85SLoGin                 continue;
109*45626c85SLoGin             }
110*45626c85SLoGin 
111*45626c85SLoGin             // 有重叠
112*45626c85SLoGin 
113*45626c85SLoGin             if range_base > base {
114*45626c85SLoGin                 num_to_add += 1;
115*45626c85SLoGin                 if insert {
116*45626c85SLoGin                     if start_index == -1 {
117*45626c85SLoGin                         start_index = i as isize;
118*45626c85SLoGin                     }
119*45626c85SLoGin                     end_index = (i + 1) as isize;
120*45626c85SLoGin                     self.do_insert_area(inner, i, base, range_base - base);
121*45626c85SLoGin                     i += 1;
122*45626c85SLoGin                 }
123*45626c85SLoGin             }
124*45626c85SLoGin 
125*45626c85SLoGin             i += 1;
126*45626c85SLoGin             base = core::cmp::min(range_end, end);
127*45626c85SLoGin         }
128*45626c85SLoGin 
129*45626c85SLoGin         if base < end {
130*45626c85SLoGin             num_to_add += 1;
131*45626c85SLoGin             if insert {
132*45626c85SLoGin                 if start_index == -1 {
133*45626c85SLoGin                     start_index = i as isize;
134*45626c85SLoGin                 }
135*45626c85SLoGin                 end_index = (i + 1) as isize;
136*45626c85SLoGin                 self.do_insert_area(inner, i, base, end - base);
137*45626c85SLoGin             }
138*45626c85SLoGin         }
139*45626c85SLoGin 
140*45626c85SLoGin         if num_to_add == 0 {
141*45626c85SLoGin             return Ok(0);
142*45626c85SLoGin         }
143*45626c85SLoGin 
144*45626c85SLoGin         if insert {
145*45626c85SLoGin             self.do_merge_blocks(inner, start_index, end_index);
146*45626c85SLoGin         }
147*45626c85SLoGin         return Ok(num_to_add);
148*45626c85SLoGin     }
149*45626c85SLoGin 
150*45626c85SLoGin     fn do_insert_area(
151*45626c85SLoGin         &self,
152*45626c85SLoGin         inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
153*45626c85SLoGin         index: usize,
154*45626c85SLoGin         base: PhysAddr,
155*45626c85SLoGin         size: usize,
156*45626c85SLoGin     ) {
157*45626c85SLoGin         let copy_elements = inner.initial_memory_regions_num - index;
158*45626c85SLoGin         inner
159*45626c85SLoGin             .initial_memory_regions
160*45626c85SLoGin             .copy_within(index..index + copy_elements, index + 1);
161*45626c85SLoGin         inner.initial_memory_regions[index] = PhysMemoryArea::new(base, size);
162*45626c85SLoGin         inner.initial_memory_regions_num += 1;
163*45626c85SLoGin     }
164*45626c85SLoGin 
165*45626c85SLoGin     fn do_merge_blocks(
166*45626c85SLoGin         &self,
167*45626c85SLoGin         inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
168*45626c85SLoGin         start_index: isize,
169*45626c85SLoGin         mut end_index: isize,
170*45626c85SLoGin     ) {
171*45626c85SLoGin         let mut i = 0;
172*45626c85SLoGin         if start_index > 0 {
173*45626c85SLoGin             i = start_index - 1;
174*45626c85SLoGin         }
175*45626c85SLoGin         end_index = core::cmp::min(end_index, inner.initial_memory_regions_num as isize - 1);
176*45626c85SLoGin 
177*45626c85SLoGin         while i < end_index {
178*45626c85SLoGin             {
179*45626c85SLoGin                 let next_base = inner.initial_memory_regions[(i + 1) as usize].base;
180*45626c85SLoGin                 let next_size = inner.initial_memory_regions[(i + 1) as usize].size;
181*45626c85SLoGin                 let this = &mut inner.initial_memory_regions[i as usize];
182*45626c85SLoGin 
183*45626c85SLoGin                 if this.base + this.size != next_base {
184*45626c85SLoGin                     // BUG_ON(this->base + this->size > next->base);
185*45626c85SLoGin                     i += 1;
186*45626c85SLoGin                     continue;
187*45626c85SLoGin                 }
188*45626c85SLoGin                 this.size += next_size;
189*45626c85SLoGin             }
190*45626c85SLoGin             // 移动后面的区域
191*45626c85SLoGin             let copy_elements = inner.initial_memory_regions_num - (i + 2) as usize;
192*45626c85SLoGin             inner.initial_memory_regions.copy_within(
193*45626c85SLoGin                 (i + 2) as usize..(i as usize + 2 + copy_elements),
194*45626c85SLoGin                 (i + 1) as usize,
195*45626c85SLoGin             );
196*45626c85SLoGin 
197*45626c85SLoGin             inner.initial_memory_regions_num -= 1;
198*45626c85SLoGin             end_index -= 1;
199*45626c85SLoGin         }
200*45626c85SLoGin     }
201*45626c85SLoGin 
202*45626c85SLoGin     /// 移除内存区域
203*45626c85SLoGin     ///
204*45626c85SLoGin     /// 如果移除的区域与已有区域有重叠,会将重叠的区域分割
205*45626c85SLoGin     #[allow(dead_code)]
206*45626c85SLoGin     pub fn remove_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
207*45626c85SLoGin         if size == 0 {
208*45626c85SLoGin             return Ok(());
209*45626c85SLoGin         }
210*45626c85SLoGin         let mut inner = self.inner.lock();
211*45626c85SLoGin         if inner.initial_memory_regions_num == 0 {
212*45626c85SLoGin             return Ok(());
213*45626c85SLoGin         }
214*45626c85SLoGin 
215*45626c85SLoGin         let (start_index, end_index) = self
216*45626c85SLoGin             .isolate_range(&mut inner, base, size)
217*45626c85SLoGin             .expect("Failed to isolate range!");
218*45626c85SLoGin 
219*45626c85SLoGin         for i in (start_index..end_index).rev() {
220*45626c85SLoGin             self.do_remove_region(&mut inner, i);
221*45626c85SLoGin         }
222*45626c85SLoGin         return Ok(());
223*45626c85SLoGin     }
224*45626c85SLoGin 
225*45626c85SLoGin     fn do_remove_region(&self, inner: &mut SpinLockGuard<'_, InnerMemBlockManager>, index: usize) {
226*45626c85SLoGin         let copy_elements = inner.initial_memory_regions_num - index - 1;
227*45626c85SLoGin         inner
228*45626c85SLoGin             .initial_memory_regions
229*45626c85SLoGin             .copy_within(index + 1..index + 1 + copy_elements, index);
230*45626c85SLoGin 
231*45626c85SLoGin         inner.initial_memory_regions_num -= 1;
232*45626c85SLoGin 
233*45626c85SLoGin         if inner.initial_memory_regions_num == 0 {
234*45626c85SLoGin             inner.initial_memory_regions[0].base = PhysAddr::new(0);
235*45626c85SLoGin             inner.initial_memory_regions[0].size = 0;
236*45626c85SLoGin         }
237*45626c85SLoGin     }
238*45626c85SLoGin 
239*45626c85SLoGin     fn isolate_range(
240*45626c85SLoGin         &self,
241*45626c85SLoGin         inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
242*45626c85SLoGin         base: PhysAddr,
243*45626c85SLoGin         size: usize,
244*45626c85SLoGin     ) -> Result<(usize, usize), SystemError> {
245*45626c85SLoGin         let end = base + size;
246*45626c85SLoGin 
247*45626c85SLoGin         let mut idx = 0;
248*45626c85SLoGin 
249*45626c85SLoGin         let mut start_index = 0;
250*45626c85SLoGin         let mut end_index = 0;
251*45626c85SLoGin 
252*45626c85SLoGin         if size == 0 {
253*45626c85SLoGin             return Ok((0, 0));
254*45626c85SLoGin         }
255*45626c85SLoGin 
256*45626c85SLoGin         while idx < inner.initial_memory_regions_num {
257*45626c85SLoGin             let range_base = inner.initial_memory_regions[idx].base;
258*45626c85SLoGin             let range_end = range_base + inner.initial_memory_regions[idx].size;
259*45626c85SLoGin 
260*45626c85SLoGin             if range_base >= end {
261*45626c85SLoGin                 break;
262*45626c85SLoGin             }
263*45626c85SLoGin             if range_end <= base {
264*45626c85SLoGin                 idx = idx.checked_add(1).unwrap_or(0);
265*45626c85SLoGin                 continue;
266*45626c85SLoGin             }
267*45626c85SLoGin 
268*45626c85SLoGin             if range_base < base {
269*45626c85SLoGin                 // regions[idx] intersects from below
270*45626c85SLoGin                 inner.initial_memory_regions[idx].base = base;
271*45626c85SLoGin                 inner.initial_memory_regions[idx].size -= base - range_base;
272*45626c85SLoGin                 self.do_insert_area(inner, idx, range_base, base - range_base);
273*45626c85SLoGin             } else if range_end > end {
274*45626c85SLoGin                 // regions[idx] intersects from above
275*45626c85SLoGin                 inner.initial_memory_regions[idx].base = end;
276*45626c85SLoGin                 inner.initial_memory_regions[idx].size -= end - range_base;
277*45626c85SLoGin 
278*45626c85SLoGin                 self.do_insert_area(inner, idx, range_base, end - range_base);
279*45626c85SLoGin                 if idx == 0 {
280*45626c85SLoGin                     idx = usize::MAX;
281*45626c85SLoGin                 } else {
282*45626c85SLoGin                     idx -= 1;
283*45626c85SLoGin                 }
284*45626c85SLoGin             } else {
285*45626c85SLoGin                 // regions[idx] is inside the range, record it
286*45626c85SLoGin                 if end_index == 0 {
287*45626c85SLoGin                     start_index = idx;
288*45626c85SLoGin                 }
289*45626c85SLoGin                 end_index = idx + 1;
290*45626c85SLoGin             }
291*45626c85SLoGin 
292*45626c85SLoGin             idx = idx.checked_add(1).unwrap_or(0);
293*45626c85SLoGin         }
294*45626c85SLoGin 
295*45626c85SLoGin         return Ok((start_index, end_index));
296*45626c85SLoGin     }
297*45626c85SLoGin 
298*45626c85SLoGin     /// 生成迭代器
299*45626c85SLoGin     pub fn to_iter(&self) -> MemBlockIter {
300*45626c85SLoGin         let inner = self.inner.lock();
301*45626c85SLoGin         return MemBlockIter { inner, index: 0 };
302*45626c85SLoGin     }
303*45626c85SLoGin 
304*45626c85SLoGin     /// 获取初始内存区域数量
305*45626c85SLoGin     pub fn total_initial_memory_regions(&self) -> usize {
306*45626c85SLoGin         let inner = self.inner.lock();
307*45626c85SLoGin         return inner.initial_memory_regions_num;
308*45626c85SLoGin     }
309*45626c85SLoGin 
310*45626c85SLoGin     /// 根据索引获取初始内存区域
311*45626c85SLoGin     pub fn get_initial_memory_region(&self, index: usize) -> Option<PhysMemoryArea> {
312*45626c85SLoGin         let inner = self.inner.lock();
313*45626c85SLoGin         return inner.initial_memory_regions.get(index).copied();
314*45626c85SLoGin     }
315*45626c85SLoGin }
316*45626c85SLoGin 
317*45626c85SLoGin pub struct MemBlockIter<'a> {
318*45626c85SLoGin     inner: SpinLockGuard<'a, InnerMemBlockManager>,
319*45626c85SLoGin     index: usize,
320*45626c85SLoGin }
321*45626c85SLoGin 
322*45626c85SLoGin #[allow(dead_code)]
323*45626c85SLoGin impl<'a> MemBlockIter<'a> {
324*45626c85SLoGin     /// 获取内存区域数量
325*45626c85SLoGin     pub fn total_num(&self) -> usize {
326*45626c85SLoGin         self.inner.initial_memory_regions_num
327*45626c85SLoGin     }
328*45626c85SLoGin 
329*45626c85SLoGin     /// 获取指定索引的内存区域
330*45626c85SLoGin     pub fn get_area(&self, index: usize) -> &PhysMemoryArea {
331*45626c85SLoGin         &self.inner.initial_memory_regions[index]
332*45626c85SLoGin     }
333*45626c85SLoGin 
334*45626c85SLoGin     /// 获取当前索引
335*45626c85SLoGin     pub fn current_index(&self) -> usize {
336*45626c85SLoGin         self.index
337*45626c85SLoGin     }
338*45626c85SLoGin }
339*45626c85SLoGin 
340*45626c85SLoGin impl<'a> Iterator for MemBlockIter<'a> {
341*45626c85SLoGin     type Item = PhysMemoryArea;
342*45626c85SLoGin 
343*45626c85SLoGin     fn next(&mut self) -> Option<Self::Item> {
344*45626c85SLoGin         if self.index >= self.inner.initial_memory_regions_num {
345*45626c85SLoGin             return None;
346*45626c85SLoGin         }
347*45626c85SLoGin         let ret = self.inner.initial_memory_regions[self.index];
348*45626c85SLoGin         self.index += 1;
349*45626c85SLoGin         return Some(ret);
350*45626c85SLoGin     }
351*45626c85SLoGin }
352