2024-01-26 10:08:39 +00:00
|
|
|
|
use core::intrinsics::unlikely;
|
|
|
|
|
|
|
2024-05-16 09:25:23 +00:00
|
|
|
|
use log::error;
|
2024-01-03 10:00:47 +00:00
|
|
|
|
use system_error::SystemError;
|
|
|
|
|
|
|
2024-02-04 06:35:18 +00:00
|
|
|
|
use crate::libs::{
|
|
|
|
|
|
align::{page_align_down, page_align_up},
|
|
|
|
|
|
spinlock::{SpinLock, SpinLockGuard},
|
|
|
|
|
|
};
|
2024-01-03 10:00:47 +00:00
|
|
|
|
|
|
|
|
|
|
use super::{PhysAddr, PhysMemoryArea};
|
|
|
|
|
|
|
|
|
|
|
|
pub const INITIAL_MEMORY_REGIONS_NUM: usize = 128;
|
|
|
|
|
|
|
|
|
|
|
|
/// 初始内存区域
|
|
|
|
|
|
static MEM_BLOCK_MANAGER: MemBlockManager = MemBlockManager::new();
|
|
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
|
pub fn mem_block_manager() -> &'static MemBlockManager {
|
|
|
|
|
|
&MEM_BLOCK_MANAGER
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 内存区域管理器
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
|
pub struct MemBlockManager {
|
|
|
|
|
|
inner: SpinLock<InnerMemBlockManager>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
|
pub struct InnerMemBlockManager {
|
|
|
|
|
|
/// 初始内存区域
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 用于记录内核启动时的内存布局, 这些区域保持升序、不重叠
|
|
|
|
|
|
initial_memory_regions: [PhysMemoryArea; INITIAL_MEMORY_REGIONS_NUM],
|
|
|
|
|
|
initial_memory_regions_num: usize,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl MemBlockManager {
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
|
pub const MIN_MEMBLOCK_ADDR: PhysAddr = PhysAddr::new(0);
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
|
pub const MAX_MEMBLOCK_ADDR: PhysAddr = PhysAddr::new(usize::MAX);
|
2025-05-29 09:40:11 +00:00
|
|
|
|
|
|
|
|
|
|
/// 由于这个函数只在全局调用,因此不需要担心栈上溢出问题
|
|
|
|
|
|
#[allow(clippy::large_stack_frames)]
|
2024-01-03 10:00:47 +00:00
|
|
|
|
const fn new() -> Self {
|
|
|
|
|
|
Self {
|
|
|
|
|
|
inner: SpinLock::new(InnerMemBlockManager {
|
|
|
|
|
|
initial_memory_regions: [PhysMemoryArea::DEFAULT; INITIAL_MEMORY_REGIONS_NUM],
|
|
|
|
|
|
initial_memory_regions_num: 0,
|
|
|
|
|
|
}),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 添加内存区域
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 如果添加的区域与已有区域有重叠,会将重叠的区域合并
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
|
pub fn add_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
|
2024-02-04 06:35:18 +00:00
|
|
|
|
let r = self.add_range(base, size, MemoryAreaAttr::empty());
|
|
|
|
|
|
return r;
|
2024-01-26 10:08:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 添加内存区域
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 如果添加的区域与已有区域有重叠,会将重叠的区域合并
|
|
|
|
|
|
fn add_range(
|
|
|
|
|
|
&self,
|
|
|
|
|
|
base: PhysAddr,
|
|
|
|
|
|
size: usize,
|
|
|
|
|
|
flags: MemoryAreaAttr,
|
|
|
|
|
|
) -> Result<(), SystemError> {
|
2024-01-03 10:00:47 +00:00
|
|
|
|
if size == 0 {
|
|
|
|
|
|
return Ok(());
|
|
|
|
|
|
}
|
|
|
|
|
|
let mut inner = self.inner.lock();
|
|
|
|
|
|
if inner.initial_memory_regions_num >= INITIAL_MEMORY_REGIONS_NUM {
|
|
|
|
|
|
panic!("Too many memory regions!");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-26 10:08:39 +00:00
|
|
|
|
let block = PhysMemoryArea::new(base, size, MemoryAreaAttr::empty());
|
2024-01-03 10:00:47 +00:00
|
|
|
|
// 特判第一个区域
|
|
|
|
|
|
if inner.initial_memory_regions_num == 0 {
|
|
|
|
|
|
inner.initial_memory_regions[0] = block;
|
|
|
|
|
|
inner.initial_memory_regions_num += 1;
|
|
|
|
|
|
return Ok(());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 先计算需要添加的区域数量
|
|
|
|
|
|
let blocks_to_add = self
|
2024-01-26 10:08:39 +00:00
|
|
|
|
.do_add_block(&mut inner, block, false, flags)
|
2024-01-03 10:00:47 +00:00
|
|
|
|
.expect("Failed to count blocks to add!");
|
|
|
|
|
|
|
|
|
|
|
|
if inner.initial_memory_regions_num + blocks_to_add > INITIAL_MEMORY_REGIONS_NUM {
|
2024-05-16 09:25:23 +00:00
|
|
|
|
error!("Too many memory regions!");
|
2024-01-03 10:00:47 +00:00
|
|
|
|
return Err(SystemError::ENOMEM);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 然后添加区域
|
2024-01-26 10:08:39 +00:00
|
|
|
|
self.do_add_block(&mut inner, block, true, flags)
|
2024-01-03 10:00:47 +00:00
|
|
|
|
.expect("Failed to add block!");
|
|
|
|
|
|
|
|
|
|
|
|
return Ok(());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn do_add_block(
|
|
|
|
|
|
&self,
|
|
|
|
|
|
inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
|
|
|
|
|
|
block: PhysMemoryArea,
|
|
|
|
|
|
insert: bool,
|
2024-01-26 10:08:39 +00:00
|
|
|
|
flags: MemoryAreaAttr,
|
2024-01-03 10:00:47 +00:00
|
|
|
|
) -> Result<usize, SystemError> {
|
|
|
|
|
|
let mut base = block.base;
|
|
|
|
|
|
let end = block.base + block.size;
|
|
|
|
|
|
let mut i = 0;
|
|
|
|
|
|
let mut start_index = -1;
|
|
|
|
|
|
let mut end_index = -1;
|
|
|
|
|
|
|
|
|
|
|
|
let mut num_to_add = 0;
|
|
|
|
|
|
|
|
|
|
|
|
while i < inner.initial_memory_regions_num {
|
|
|
|
|
|
let range_base = inner.initial_memory_regions[i].base;
|
|
|
|
|
|
let range_end =
|
|
|
|
|
|
inner.initial_memory_regions[i].base + inner.initial_memory_regions[i].size;
|
|
|
|
|
|
|
|
|
|
|
|
if range_base >= end {
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if range_end <= base {
|
|
|
|
|
|
i += 1;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 有重叠
|
|
|
|
|
|
|
|
|
|
|
|
if range_base > base {
|
|
|
|
|
|
num_to_add += 1;
|
|
|
|
|
|
if insert {
|
|
|
|
|
|
if start_index == -1 {
|
|
|
|
|
|
start_index = i as isize;
|
|
|
|
|
|
}
|
|
|
|
|
|
end_index = (i + 1) as isize;
|
2024-01-26 10:08:39 +00:00
|
|
|
|
self.do_insert_area(inner, i, base, range_base - base, flags);
|
2024-01-03 10:00:47 +00:00
|
|
|
|
i += 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
i += 1;
|
|
|
|
|
|
base = core::cmp::min(range_end, end);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if base < end {
|
|
|
|
|
|
num_to_add += 1;
|
|
|
|
|
|
if insert {
|
|
|
|
|
|
if start_index == -1 {
|
|
|
|
|
|
start_index = i as isize;
|
|
|
|
|
|
}
|
|
|
|
|
|
end_index = (i + 1) as isize;
|
2024-01-26 10:08:39 +00:00
|
|
|
|
self.do_insert_area(inner, i, base, end - base, flags);
|
2024-01-03 10:00:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if num_to_add == 0 {
|
|
|
|
|
|
return Ok(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if insert {
|
|
|
|
|
|
self.do_merge_blocks(inner, start_index, end_index);
|
|
|
|
|
|
}
|
|
|
|
|
|
return Ok(num_to_add);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn do_insert_area(
|
|
|
|
|
|
&self,
|
|
|
|
|
|
inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
|
|
|
|
|
|
index: usize,
|
|
|
|
|
|
base: PhysAddr,
|
|
|
|
|
|
size: usize,
|
2024-01-26 10:08:39 +00:00
|
|
|
|
flags: MemoryAreaAttr,
|
2024-01-03 10:00:47 +00:00
|
|
|
|
) {
|
|
|
|
|
|
let copy_elements = inner.initial_memory_regions_num - index;
|
|
|
|
|
|
inner
|
|
|
|
|
|
.initial_memory_regions
|
|
|
|
|
|
.copy_within(index..index + copy_elements, index + 1);
|
2024-01-26 10:08:39 +00:00
|
|
|
|
inner.initial_memory_regions[index] = PhysMemoryArea::new(base, size, flags);
|
2024-01-03 10:00:47 +00:00
|
|
|
|
inner.initial_memory_regions_num += 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn do_merge_blocks(
|
|
|
|
|
|
&self,
|
|
|
|
|
|
inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
|
|
|
|
|
|
start_index: isize,
|
|
|
|
|
|
mut end_index: isize,
|
|
|
|
|
|
) {
|
|
|
|
|
|
let mut i = 0;
|
|
|
|
|
|
if start_index > 0 {
|
|
|
|
|
|
i = start_index - 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
end_index = core::cmp::min(end_index, inner.initial_memory_regions_num as isize - 1);
|
|
|
|
|
|
|
|
|
|
|
|
while i < end_index {
|
|
|
|
|
|
{
|
|
|
|
|
|
let next_base = inner.initial_memory_regions[(i + 1) as usize].base;
|
|
|
|
|
|
let next_size = inner.initial_memory_regions[(i + 1) as usize].size;
|
2024-01-26 10:08:39 +00:00
|
|
|
|
let next_flags = inner.initial_memory_regions[(i + 1) as usize].flags;
|
2024-01-03 10:00:47 +00:00
|
|
|
|
let this = &mut inner.initial_memory_regions[i as usize];
|
|
|
|
|
|
|
2024-01-26 10:08:39 +00:00
|
|
|
|
if this.base + this.size != next_base || this.flags != next_flags {
|
|
|
|
|
|
if unlikely(this.base + this.size > next_base) {
|
2024-05-16 09:25:23 +00:00
|
|
|
|
panic!("this->base + this->size > next->base");
|
2024-01-26 10:08:39 +00:00
|
|
|
|
}
|
2024-01-03 10:00:47 +00:00
|
|
|
|
i += 1;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
this.size += next_size;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 移动后面的区域
|
|
|
|
|
|
let copy_elements = inner.initial_memory_regions_num - (i + 2) as usize;
|
|
|
|
|
|
inner.initial_memory_regions.copy_within(
|
|
|
|
|
|
(i + 2) as usize..(i as usize + 2 + copy_elements),
|
|
|
|
|
|
(i + 1) as usize,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
inner.initial_memory_regions_num -= 1;
|
|
|
|
|
|
end_index -= 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 移除内存区域
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 如果移除的区域与已有区域有重叠,会将重叠的区域分割
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
|
pub fn remove_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
|
|
|
|
|
|
if size == 0 {
|
|
|
|
|
|
return Ok(());
|
|
|
|
|
|
}
|
|
|
|
|
|
let mut inner = self.inner.lock();
|
|
|
|
|
|
if inner.initial_memory_regions_num == 0 {
|
|
|
|
|
|
return Ok(());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let (start_index, end_index) = self
|
|
|
|
|
|
.isolate_range(&mut inner, base, size)
|
|
|
|
|
|
.expect("Failed to isolate range!");
|
|
|
|
|
|
|
|
|
|
|
|
for i in (start_index..end_index).rev() {
|
|
|
|
|
|
self.do_remove_region(&mut inner, i);
|
|
|
|
|
|
}
|
|
|
|
|
|
return Ok(());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn do_remove_region(&self, inner: &mut SpinLockGuard<'_, InnerMemBlockManager>, index: usize) {
|
|
|
|
|
|
let copy_elements = inner.initial_memory_regions_num - index - 1;
|
|
|
|
|
|
inner
|
|
|
|
|
|
.initial_memory_regions
|
|
|
|
|
|
.copy_within(index + 1..index + 1 + copy_elements, index);
|
|
|
|
|
|
|
|
|
|
|
|
inner.initial_memory_regions_num -= 1;
|
|
|
|
|
|
|
|
|
|
|
|
if inner.initial_memory_regions_num == 0 {
|
|
|
|
|
|
inner.initial_memory_regions[0].base = PhysAddr::new(0);
|
|
|
|
|
|
inner.initial_memory_regions[0].size = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-26 10:08:39 +00:00
|
|
|
|
/// 在一个内存块管理器中找到一个物理地址范围内的
|
|
|
|
|
|
/// 空闲块,并隔离出所需的内存大小
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ## 返回值
|
|
|
|
|
|
///
|
|
|
|
|
|
/// - Ok((start_index, end_index)) 表示成功找到了一个连续的内存区域来满足所需的 size。这里:
|
|
|
|
|
|
/// - start_index 是指定的起始内存区域的索引。
|
|
|
|
|
|
/// - end_index 是指定的结束内存区域的索引,它实际上不包含在返回的连续区域中,但它标志着下一个可能的不连续区域的开始。
|
|
|
|
|
|
/// - Err(SystemError) 则表示没有找到足够的空间来满足请求的 size,可能是因为内存区域不足或存在其他系统错误
|
2024-01-03 10:00:47 +00:00
|
|
|
|
fn isolate_range(
|
|
|
|
|
|
&self,
|
|
|
|
|
|
inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
|
|
|
|
|
|
base: PhysAddr,
|
|
|
|
|
|
size: usize,
|
|
|
|
|
|
) -> Result<(usize, usize), SystemError> {
|
|
|
|
|
|
let end = base + size;
|
|
|
|
|
|
|
|
|
|
|
|
let mut idx = 0;
|
|
|
|
|
|
|
|
|
|
|
|
let mut start_index = 0;
|
|
|
|
|
|
let mut end_index = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if size == 0 {
|
|
|
|
|
|
return Ok((0, 0));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while idx < inner.initial_memory_regions_num {
|
|
|
|
|
|
let range_base = inner.initial_memory_regions[idx].base;
|
|
|
|
|
|
let range_end = range_base + inner.initial_memory_regions[idx].size;
|
|
|
|
|
|
|
|
|
|
|
|
if range_base >= end {
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if range_end <= base {
|
|
|
|
|
|
idx = idx.checked_add(1).unwrap_or(0);
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if range_base < base {
|
|
|
|
|
|
// regions[idx] intersects from below
|
|
|
|
|
|
inner.initial_memory_regions[idx].base = base;
|
|
|
|
|
|
inner.initial_memory_regions[idx].size -= base - range_base;
|
2024-01-26 10:08:39 +00:00
|
|
|
|
self.do_insert_area(
|
|
|
|
|
|
inner,
|
|
|
|
|
|
idx,
|
|
|
|
|
|
range_base,
|
|
|
|
|
|
base - range_base,
|
|
|
|
|
|
inner.initial_memory_regions[idx].flags,
|
|
|
|
|
|
);
|
2024-01-03 10:00:47 +00:00
|
|
|
|
} else if range_end > end {
|
|
|
|
|
|
// regions[idx] intersects from above
|
|
|
|
|
|
inner.initial_memory_regions[idx].base = end;
|
|
|
|
|
|
inner.initial_memory_regions[idx].size -= end - range_base;
|
|
|
|
|
|
|
2024-01-26 10:08:39 +00:00
|
|
|
|
self.do_insert_area(
|
|
|
|
|
|
inner,
|
|
|
|
|
|
idx,
|
|
|
|
|
|
range_base,
|
|
|
|
|
|
end - range_base,
|
|
|
|
|
|
inner.initial_memory_regions[idx].flags,
|
|
|
|
|
|
);
|
2024-01-03 10:00:47 +00:00
|
|
|
|
if idx == 0 {
|
|
|
|
|
|
idx = usize::MAX;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
idx -= 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// regions[idx] is inside the range, record it
|
|
|
|
|
|
if end_index == 0 {
|
|
|
|
|
|
start_index = idx;
|
|
|
|
|
|
}
|
|
|
|
|
|
end_index = idx + 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
idx = idx.checked_add(1).unwrap_or(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return Ok((start_index, end_index));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-26 10:08:39 +00:00
|
|
|
|
/// mark_nomap - 用`MemoryAreaAttr::NOMAP`标志标记内存区域
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ## 参数
|
|
|
|
|
|
///
|
|
|
|
|
|
/// - base: 区域的物理基地址
|
|
|
|
|
|
/// - size: 区域的大小
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 使用`MemoryAreaAttr::NOMAP`标志标记的内存区域将不会被添加到物理内存的直接映射中。这些区域仍然会被内存映射所覆盖。内存映射中代表NOMAP内存帧的struct page将被PageReserved()。
|
|
|
|
|
|
/// 注意:如果被标记为`MemoryAreaAttr::NOMAP`的内存是从memblock分配的,调用者必须忽略该内存
|
|
|
|
|
|
pub fn mark_nomap(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
|
|
|
|
|
|
return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::NOMAP);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-26 03:59:47 +00:00
|
|
|
|
/// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/mm/memblock.c?fi=memblock_mark_mirror#940
|
|
|
|
|
|
pub fn mark_mirror(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
|
|
|
|
|
|
return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::MIRROR);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-26 10:08:39 +00:00
|
|
|
|
fn set_or_clear_flags(
|
|
|
|
|
|
&self,
|
2024-02-04 06:35:18 +00:00
|
|
|
|
mut base: PhysAddr,
|
|
|
|
|
|
mut size: usize,
|
2024-01-26 10:08:39 +00:00
|
|
|
|
set: bool,
|
|
|
|
|
|
flags: MemoryAreaAttr,
|
|
|
|
|
|
) -> Result<(), SystemError> {
|
2024-02-04 06:35:18 +00:00
|
|
|
|
let rsvd_base = PhysAddr::new(page_align_down(base.data()));
|
2024-03-22 15:26:39 +00:00
|
|
|
|
size = page_align_up(size + base.data() - rsvd_base.data());
|
2024-02-04 06:35:18 +00:00
|
|
|
|
base = rsvd_base;
|
|
|
|
|
|
|
2024-01-26 10:08:39 +00:00
|
|
|
|
let mut inner = self.inner.lock();
|
|
|
|
|
|
let (start_index, end_index) = self.isolate_range(&mut inner, base, size)?;
|
|
|
|
|
|
for i in start_index..end_index {
|
|
|
|
|
|
if set {
|
|
|
|
|
|
inner.initial_memory_regions[i].flags |= flags;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
inner.initial_memory_regions[i].flags &= !flags;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let num = inner.initial_memory_regions_num as isize;
|
|
|
|
|
|
self.do_merge_blocks(&mut inner, 0, num);
|
|
|
|
|
|
return Ok(());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 标记内存区域为保留区域
|
|
|
|
|
|
pub fn reserve_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
|
|
|
|
|
|
return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::RESERVED);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-04 06:35:18 +00:00
|
|
|
|
/// 判断[base, base+size)与已有区域是否有重叠
|
|
|
|
|
|
pub fn is_overlapped(&self, base: PhysAddr, size: usize) -> bool {
|
|
|
|
|
|
let inner = self.inner.lock();
|
|
|
|
|
|
return self.do_is_overlapped(base, size, false, &inner);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 判断[base, base+size)与已有Reserved区域是否有重叠
|
|
|
|
|
|
pub fn is_overlapped_with_reserved(&self, base: PhysAddr, size: usize) -> bool {
|
|
|
|
|
|
let inner = self.inner.lock();
|
|
|
|
|
|
return self.do_is_overlapped(base, size, true, &inner);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn do_is_overlapped(
|
|
|
|
|
|
&self,
|
|
|
|
|
|
base: PhysAddr,
|
|
|
|
|
|
size: usize,
|
|
|
|
|
|
require_reserved: bool,
|
|
|
|
|
|
inner: &SpinLockGuard<'_, InnerMemBlockManager>,
|
|
|
|
|
|
) -> bool {
|
|
|
|
|
|
let mut res = false;
|
|
|
|
|
|
for i in 0..inner.initial_memory_regions_num {
|
|
|
|
|
|
if require_reserved
|
|
|
|
|
|
&& !inner.initial_memory_regions[i]
|
|
|
|
|
|
.flags
|
|
|
|
|
|
.contains(MemoryAreaAttr::RESERVED)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 忽略非保留区域
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let range_base = inner.initial_memory_regions[i].base;
|
|
|
|
|
|
let range_end = range_base + inner.initial_memory_regions[i].size;
|
|
|
|
|
|
if (base >= range_base && base < range_end)
|
|
|
|
|
|
|| (base + size > range_base && base + size <= range_end)
|
|
|
|
|
|
|| (base <= range_base && base + size >= range_end)
|
|
|
|
|
|
{
|
|
|
|
|
|
res = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-03 10:00:47 +00:00
|
|
|
|
/// 生成迭代器
|
|
|
|
|
|
pub fn to_iter(&self) -> MemBlockIter {
|
|
|
|
|
|
let inner = self.inner.lock();
|
2024-02-04 06:35:18 +00:00
|
|
|
|
return MemBlockIter {
|
|
|
|
|
|
inner,
|
|
|
|
|
|
index: 0,
|
|
|
|
|
|
usable_only: false,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 生成迭代器,迭代所有可用的物理内存区域
|
|
|
|
|
|
pub fn to_iter_available(&self) -> MemBlockIter {
|
|
|
|
|
|
let inner = self.inner.lock();
|
|
|
|
|
|
return MemBlockIter {
|
|
|
|
|
|
inner,
|
|
|
|
|
|
index: 0,
|
|
|
|
|
|
usable_only: true,
|
|
|
|
|
|
};
|
2024-01-03 10:00:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 获取初始内存区域数量
|
|
|
|
|
|
pub fn total_initial_memory_regions(&self) -> usize {
|
|
|
|
|
|
let inner = self.inner.lock();
|
|
|
|
|
|
return inner.initial_memory_regions_num;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 根据索引获取初始内存区域
|
|
|
|
|
|
pub fn get_initial_memory_region(&self, index: usize) -> Option<PhysMemoryArea> {
|
|
|
|
|
|
let inner = self.inner.lock();
|
|
|
|
|
|
return inner.initial_memory_regions.get(index).copied();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub struct MemBlockIter<'a> {
|
|
|
|
|
|
inner: SpinLockGuard<'a, InnerMemBlockManager>,
|
|
|
|
|
|
index: usize,
|
2024-02-04 06:35:18 +00:00
|
|
|
|
usable_only: bool,
|
2024-01-03 10:00:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
2024-11-11 13:29:15 +00:00
|
|
|
|
impl MemBlockIter<'_> {
|
2024-01-03 10:00:47 +00:00
|
|
|
|
/// 获取内存区域数量
|
|
|
|
|
|
pub fn total_num(&self) -> usize {
|
|
|
|
|
|
self.inner.initial_memory_regions_num
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 获取指定索引的内存区域
|
|
|
|
|
|
pub fn get_area(&self, index: usize) -> &PhysMemoryArea {
|
|
|
|
|
|
&self.inner.initial_memory_regions[index]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 获取当前索引
|
|
|
|
|
|
pub fn current_index(&self) -> usize {
|
|
|
|
|
|
self.index
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-11 13:29:15 +00:00
|
|
|
|
impl Iterator for MemBlockIter<'_> {
|
2024-01-03 10:00:47 +00:00
|
|
|
|
type Item = PhysMemoryArea;
|
|
|
|
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
2024-02-04 06:35:18 +00:00
|
|
|
|
while self.index < self.inner.initial_memory_regions_num {
|
2024-03-22 15:26:39 +00:00
|
|
|
|
if self.usable_only
|
|
|
|
|
|
&& !self.inner.initial_memory_regions[self.index]
|
2024-02-04 06:35:18 +00:00
|
|
|
|
.flags
|
|
|
|
|
|
.is_empty()
|
2024-03-22 15:26:39 +00:00
|
|
|
|
{
|
|
|
|
|
|
self.index += 1;
|
|
|
|
|
|
if self.index >= self.inner.initial_memory_regions_num {
|
|
|
|
|
|
return None;
|
2024-02-04 06:35:18 +00:00
|
|
|
|
}
|
2024-03-22 15:26:39 +00:00
|
|
|
|
continue;
|
2024-02-04 06:35:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2024-01-03 10:00:47 +00:00
|
|
|
|
if self.index >= self.inner.initial_memory_regions_num {
|
|
|
|
|
|
return None;
|
|
|
|
|
|
}
|
|
|
|
|
|
let ret = self.inner.initial_memory_regions[self.index];
|
|
|
|
|
|
self.index += 1;
|
|
|
|
|
|
return Some(ret);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-01-26 10:08:39 +00:00
|
|
|
|
|
|
|
|
|
|
bitflags! {
|
|
|
|
|
|
/// 内存区域属性
|
2024-03-22 15:26:39 +00:00
|
|
|
|
#[allow(clippy::bad_bit_mask)]
|
2024-01-26 10:08:39 +00:00
|
|
|
|
pub struct MemoryAreaAttr: u32 {
|
|
|
|
|
|
/// No special request
|
|
|
|
|
|
const NONE = 0x0;
|
|
|
|
|
|
/// Hotpluggable region
|
|
|
|
|
|
const HOTPLUG = (1 << 0);
|
|
|
|
|
|
/// Mirrored region
|
|
|
|
|
|
const MIRROR = (1 << 1);
|
|
|
|
|
|
/// do not add to kenrel direct mapping
|
|
|
|
|
|
const NOMAP = (1 << 2);
|
|
|
|
|
|
/// Always detected via a driver
|
|
|
|
|
|
const DRIVER_MANAGED = (1 << 3);
|
|
|
|
|
|
/// Memory is reserved
|
|
|
|
|
|
const RESERVED = (1 << 4);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|