|  | @@ -1,8 +1,9 @@
 | 
	
		
			
				|  |  |  use crate::libs::spinlock::{SpinLock, SpinLockGuard};
 | 
	
		
			
				|  |  |  use crate::mm::kernel_mapper::KernelMapper;
 | 
	
		
			
				|  |  | +use crate::mm::page::{PAGE_1G_SHIFT, PAGE_4K_SHIFT};
 | 
	
		
			
				|  |  |  use crate::process::ProcessManager;
 | 
	
		
			
				|  |  |  use crate::{
 | 
	
		
			
				|  |  | -    include::bindings::bindings::{PAGE_1G_SHIFT, PAGE_4K_SHIFT, PAGE_4K_SIZE},
 | 
	
		
			
				|  |  | +    include::bindings::bindings::PAGE_4K_SIZE,
 | 
	
		
			
				|  |  |      kdebug,
 | 
	
		
			
				|  |  |      mm::{MMArch, MemoryManagementArch},
 | 
	
		
			
				|  |  |  };
 | 
	
	
		
			
				|  | @@ -10,22 +11,19 @@ use crate::{kerror, kinfo, kwarn};
 | 
	
		
			
				|  |  |  use alloc::{collections::LinkedList, vec::Vec};
 | 
	
		
			
				|  |  |  use core::mem;
 | 
	
		
			
				|  |  |  use core::mem::MaybeUninit;
 | 
	
		
			
				|  |  | -use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
 | 
	
		
			
				|  |  | +use core::sync::atomic::{AtomicBool, Ordering};
 | 
	
		
			
				|  |  |  use system_error::SystemError;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  use super::page::PageFlags;
 | 
	
		
			
				|  |  |  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_BASE: VirtAddr = VirtAddr::new(0xffffa10000000000);
 | 
	
		
			
				|  |  | -const MMIO_TOP: VirtAddr = VirtAddr::new(0xffffa20000000000);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  const PAGE_1G_SIZE: usize = 1 << 30;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static mut __MMIO_POOL: Option<MmioBuddyMemPool> = None;
 | 
	
	
		
			
				|  | @@ -65,26 +63,35 @@ impl 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,
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        assert!(pool.pool_start_addr.data() % PAGE_1G_SIZE == 0);
 | 
	
		
			
				|  |  |          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");
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          kdebug!("MMIO buddy pool init success");
 | 
	
		
			
				|  |  |          return pool;
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -297,9 +304,9 @@ impl MmioBuddyMemPool {
 | 
	
		
			
				|  |  |      /// @return Ok(MmioBuddyAddrRegion)符合要求的内存块信息结构体。
 | 
	
		
			
				|  |  |      /// @return Err(MmioResult) 没有满足要求的内存块时,返回__query_addr_region的错误码。
 | 
	
		
			
				|  |  |      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),
 | 
	
		
			
				|  |  |              Err(err) => {
 | 
	
		
			
				|  |  |                  kdebug!("mmio_buddy_query_addr_region failed");
 | 
	
	
		
			
				|  | @@ -487,9 +494,9 @@ impl MmioBuddyMemPool {
 | 
	
		
			
				|  |  |          let mut new_size = size;
 | 
	
		
			
				|  |  |          // 对齐要申请的空间大小
 | 
	
		
			
				|  |  |          // 如果要申请的空间大小小于4k,则分配4k
 | 
	
		
			
				|  |  | -        if size_exp < PAGE_4K_SHIFT {
 | 
	
		
			
				|  |  | +        if size_exp < PAGE_4K_SHIFT as u32 {
 | 
	
		
			
				|  |  |              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 {
 | 
	
		
			
				|  |  |              // 向左对齐空间大小
 | 
	
		
			
				|  |  |              size_exp += 1;
 | 
	
	
		
			
				|  | @@ -630,7 +637,8 @@ impl MMIOSpaceGuard {
 | 
	
		
			
				|  |  |              "MMIO space vaddr must be aligned with size"
 | 
	
		
			
				|  |  |          );
 | 
	
		
			
				|  |  |          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"
 | 
	
		
			
				|  |  |          );
 | 
	
		
			
				|  |  |  
 |