|
@@ -1,8 +1,9 @@
|
|
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
|
|
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
|
|
use crate::mm::kernel_mapper::KernelMapper;
|
|
use crate::mm::kernel_mapper::KernelMapper;
|
|
|
|
+use crate::mm::page::{PAGE_1G_SHIFT, PAGE_4K_SHIFT};
|
|
use crate::process::ProcessManager;
|
|
use crate::process::ProcessManager;
|
|
use crate::{
|
|
use crate::{
|
|
- include::bindings::bindings::{PAGE_1G_SHIFT, PAGE_4K_SHIFT, PAGE_4K_SIZE},
|
|
|
|
|
|
+ include::bindings::bindings::PAGE_4K_SIZE,
|
|
kdebug,
|
|
kdebug,
|
|
mm::{MMArch, MemoryManagementArch},
|
|
mm::{MMArch, MemoryManagementArch},
|
|
};
|
|
};
|
|
@@ -10,22 +11,19 @@ use crate::{kerror, kinfo, kwarn};
|
|
use alloc::{collections::LinkedList, vec::Vec};
|
|
use alloc::{collections::LinkedList, vec::Vec};
|
|
use core::mem;
|
|
use core::mem;
|
|
use core::mem::MaybeUninit;
|
|
use core::mem::MaybeUninit;
|
|
-use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
|
|
|
|
|
|
+use core::sync::atomic::{AtomicBool, Ordering};
|
|
use system_error::SystemError;
|
|
use system_error::SystemError;
|
|
|
|
|
|
use super::page::PageFlags;
|
|
use super::page::PageFlags;
|
|
use super::{PhysAddr, VirtAddr};
|
|
use super::{PhysAddr, VirtAddr};
|
|
|
|
|
|
// 最大的伙伴块的幂
|
|
// 最大的伙伴块的幂
|
|
-const MMIO_BUDDY_MAX_EXP: u32 = PAGE_1G_SHIFT;
|
|
|
|
|
|
+const MMIO_BUDDY_MAX_EXP: u32 = PAGE_1G_SHIFT as u32;
|
|
// 最小的伙伴块的幂
|
|
// 最小的伙伴块的幂
|
|
-const MMIO_BUDDY_MIN_EXP: u32 = PAGE_4K_SHIFT;
|
|
|
|
|
|
+const MMIO_BUDDY_MIN_EXP: u32 = PAGE_4K_SHIFT as u32;
|
|
// 内存池数组的范围
|
|
// 内存池数组的范围
|
|
const MMIO_BUDDY_REGION_COUNT: u32 = MMIO_BUDDY_MAX_EXP - MMIO_BUDDY_MIN_EXP + 1;
|
|
const MMIO_BUDDY_REGION_COUNT: u32 = MMIO_BUDDY_MAX_EXP - MMIO_BUDDY_MIN_EXP + 1;
|
|
|
|
|
|
-const MMIO_BASE: VirtAddr = VirtAddr::new(0xffffa10000000000);
|
|
|
|
-const MMIO_TOP: VirtAddr = VirtAddr::new(0xffffa20000000000);
|
|
|
|
-
|
|
|
|
const PAGE_1G_SIZE: usize = 1 << 30;
|
|
const PAGE_1G_SIZE: usize = 1 << 30;
|
|
|
|
|
|
static mut __MMIO_POOL: Option<MmioBuddyMemPool> = None;
|
|
static mut __MMIO_POOL: Option<MmioBuddyMemPool> = None;
|
|
@@ -65,26 +63,35 @@ impl MmioBuddyMemPool {
|
|
};
|
|
};
|
|
|
|
|
|
let pool = MmioBuddyMemPool {
|
|
let pool = MmioBuddyMemPool {
|
|
- pool_start_addr: MMIO_BASE,
|
|
|
|
- pool_size: MMIO_TOP - MMIO_BASE,
|
|
|
|
|
|
+ pool_start_addr: MMArch::MMIO_BASE,
|
|
|
|
+ pool_size: MMArch::MMIO_SIZE,
|
|
free_regions,
|
|
free_regions,
|
|
};
|
|
};
|
|
|
|
+
|
|
|
|
+ assert!(pool.pool_start_addr.data() % PAGE_1G_SIZE == 0);
|
|
kdebug!("MMIO buddy pool init: created");
|
|
kdebug!("MMIO buddy pool init: created");
|
|
|
|
|
|
- let cnt_1g_blocks = (MMIO_TOP - MMIO_BASE) >> 30;
|
|
|
|
- let mut vaddr_base = MMIO_BASE;
|
|
|
|
- kdebug!("total 1G blocks: {cnt_1g_blocks}");
|
|
|
|
- for _i in 0..cnt_1g_blocks {
|
|
|
|
- compiler_fence(Ordering::SeqCst);
|
|
|
|
- match pool.give_back_block(vaddr_base, PAGE_1G_SHIFT) {
|
|
|
|
- Ok(_) => {
|
|
|
|
- vaddr_base += PAGE_1G_SIZE;
|
|
|
|
- }
|
|
|
|
- Err(_) => {
|
|
|
|
|
|
+ let mut vaddr_base = MMArch::MMIO_BASE;
|
|
|
|
+ let mut remain_size = MMArch::MMIO_SIZE;
|
|
|
|
+ kdebug!(
|
|
|
|
+ "BASE: {:?}, TOP: {:?}, size: {:?}",
|
|
|
|
+ MMArch::MMIO_BASE,
|
|
|
|
+ MMArch::MMIO_TOP,
|
|
|
|
+ MMArch::MMIO_SIZE
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ for shift in (PAGE_4K_SHIFT..=PAGE_1G_SHIFT).rev() {
|
|
|
|
+ if remain_size & (1 << shift) != 0 {
|
|
|
|
+ let ok = pool.give_back_block(vaddr_base, shift as u32).is_ok();
|
|
|
|
+ if ok {
|
|
|
|
+ vaddr_base += 1 << shift;
|
|
|
|
+ remain_size -= 1 << shift;
|
|
|
|
+ } else {
|
|
panic!("MMIO buddy pool init failed");
|
|
panic!("MMIO buddy pool init failed");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
kdebug!("MMIO buddy pool init success");
|
|
kdebug!("MMIO buddy pool init success");
|
|
return pool;
|
|
return pool;
|
|
}
|
|
}
|
|
@@ -297,9 +304,9 @@ impl MmioBuddyMemPool {
|
|
/// @return Ok(MmioBuddyAddrRegion)符合要求的内存块信息结构体。
|
|
/// @return Ok(MmioBuddyAddrRegion)符合要求的内存块信息结构体。
|
|
/// @return Err(MmioResult) 没有满足要求的内存块时,返回__query_addr_region的错误码。
|
|
/// @return Err(MmioResult) 没有满足要求的内存块时,返回__query_addr_region的错误码。
|
|
fn mmio_buddy_query_addr_region(&self, exp: u32) -> Result<MmioBuddyAddrRegion, MmioResult> {
|
|
fn mmio_buddy_query_addr_region(&self, exp: u32) -> Result<MmioBuddyAddrRegion, MmioResult> {
|
|
- let list_guard: &mut SpinLockGuard<MmioFreeRegionList> =
|
|
|
|
- &mut self.free_regions[exp2index(exp)].lock();
|
|
|
|
- match self.query_addr_region(exp, list_guard) {
|
|
|
|
|
|
+ let mut list_guard: SpinLockGuard<MmioFreeRegionList> =
|
|
|
|
+ self.free_regions[exp2index(exp)].lock();
|
|
|
|
+ match self.query_addr_region(exp, &mut list_guard) {
|
|
Ok(ret) => return Ok(ret),
|
|
Ok(ret) => return Ok(ret),
|
|
Err(err) => {
|
|
Err(err) => {
|
|
kdebug!("mmio_buddy_query_addr_region failed");
|
|
kdebug!("mmio_buddy_query_addr_region failed");
|
|
@@ -487,9 +494,9 @@ impl MmioBuddyMemPool {
|
|
let mut new_size = size;
|
|
let mut new_size = size;
|
|
// 对齐要申请的空间大小
|
|
// 对齐要申请的空间大小
|
|
// 如果要申请的空间大小小于4k,则分配4k
|
|
// 如果要申请的空间大小小于4k,则分配4k
|
|
- if size_exp < PAGE_4K_SHIFT {
|
|
|
|
|
|
+ if size_exp < PAGE_4K_SHIFT as u32 {
|
|
new_size = PAGE_4K_SIZE as usize;
|
|
new_size = PAGE_4K_SIZE as usize;
|
|
- size_exp = PAGE_4K_SHIFT;
|
|
|
|
|
|
+ size_exp = PAGE_4K_SHIFT as u32;
|
|
} else if (new_size & (!(1 << size_exp))) != 0 {
|
|
} else if (new_size & (!(1 << size_exp))) != 0 {
|
|
// 向左对齐空间大小
|
|
// 向左对齐空间大小
|
|
size_exp += 1;
|
|
size_exp += 1;
|
|
@@ -630,7 +637,8 @@ impl MMIOSpaceGuard {
|
|
"MMIO space vaddr must be aligned with size"
|
|
"MMIO space vaddr must be aligned with size"
|
|
);
|
|
);
|
|
assert!(
|
|
assert!(
|
|
- vaddr.data() >= MMIO_BASE.data() && vaddr.data() + size <= MMIO_TOP.data(),
|
|
|
|
|
|
+ vaddr.data() >= MMArch::MMIO_BASE.data()
|
|
|
|
+ && vaddr.data() + size <= MMArch::MMIO_TOP.data(),
|
|
"MMIO space must be in MMIO region"
|
|
"MMIO space must be in MMIO region"
|
|
);
|
|
);
|
|
|
|
|