177799ccaSWu Mianzhi use crate::arch::mm::kernel_page_flags; 277799ccaSWu Mianzhi 377799ccaSWu Mianzhi use crate::arch::MMArch; 477799ccaSWu Mianzhi 577799ccaSWu Mianzhi use crate::mm::kernel_mapper::KernelMapper; 677799ccaSWu Mianzhi use crate::mm::page::PageFlags; 777799ccaSWu Mianzhi use crate::mm::{ 877799ccaSWu Mianzhi allocator::page_frame::{ 977799ccaSWu Mianzhi allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame, 1077799ccaSWu Mianzhi }, 1177799ccaSWu Mianzhi MemoryManagementArch, PhysAddr, VirtAddr, 1277799ccaSWu Mianzhi }; 1377799ccaSWu Mianzhi use core::ptr::NonNull; 1477799ccaSWu Mianzhi const PAGE_SIZE: usize = 4096; 1577799ccaSWu Mianzhi /// @brief 申请用于DMA的内存页 1677799ccaSWu Mianzhi /// @param pages 页数(4k一页) 1777799ccaSWu Mianzhi /// @return PhysAddr 获得的内存页的初始物理地址 1877799ccaSWu Mianzhi pub fn dma_alloc(pages: usize) -> (usize, NonNull<u8>) { 1977799ccaSWu Mianzhi let page_num = PageFrameCount::new( 2077799ccaSWu Mianzhi ((pages * PAGE_SIZE + MMArch::PAGE_SIZE - 1) / MMArch::PAGE_SIZE).next_power_of_two(), 2177799ccaSWu Mianzhi ); 2277799ccaSWu Mianzhi unsafe { 2377799ccaSWu Mianzhi let (paddr, count) = allocate_page_frames(page_num).expect("e1000e: alloc page failed"); 2477799ccaSWu Mianzhi let virt = MMArch::phys_2_virt(paddr).unwrap(); 2577799ccaSWu Mianzhi // 清空这块区域,防止出现脏数据 2677799ccaSWu Mianzhi core::ptr::write_bytes(virt.data() as *mut u8, 0, count.data() * MMArch::PAGE_SIZE); 2777799ccaSWu Mianzhi 2877799ccaSWu Mianzhi let dma_flags: PageFlags<MMArch> = PageFlags::mmio_flags(); 2977799ccaSWu Mianzhi 3077799ccaSWu Mianzhi let mut kernel_mapper = KernelMapper::lock(); 3177799ccaSWu Mianzhi let kernel_mapper = kernel_mapper.as_mut().unwrap(); 3277799ccaSWu Mianzhi let flusher = kernel_mapper 3377799ccaSWu Mianzhi .remap(virt, dma_flags) 3477799ccaSWu Mianzhi .expect("e1000e: remap failed"); 3577799ccaSWu Mianzhi flusher.flush(); 3677799ccaSWu Mianzhi return ( 3777799ccaSWu Mianzhi paddr.data(), 3877799ccaSWu Mianzhi NonNull::new(MMArch::phys_2_virt(paddr).unwrap().data() as _).unwrap(), 3977799ccaSWu Mianzhi ); 4077799ccaSWu Mianzhi } 4177799ccaSWu Mianzhi } 4277799ccaSWu Mianzhi /// @brief 释放用于DMA的内存页 4377799ccaSWu Mianzhi /// @param paddr 起始物理地址 pages 页数(4k一页) 4477799ccaSWu Mianzhi /// @return i32 0表示成功 4577799ccaSWu Mianzhi pub unsafe fn dma_dealloc(paddr: usize, vaddr: NonNull<u8>, pages: usize) -> i32 { 4677799ccaSWu Mianzhi let page_count = PageFrameCount::new( 4777799ccaSWu Mianzhi ((pages * PAGE_SIZE + MMArch::PAGE_SIZE - 1) / MMArch::PAGE_SIZE).next_power_of_two(), 4877799ccaSWu Mianzhi ); 4977799ccaSWu Mianzhi 5077799ccaSWu Mianzhi // 恢复页面属性 51*b5b571e0SLoGin let vaddr = VirtAddr::new(vaddr.as_ptr() as usize); 5277799ccaSWu Mianzhi let mut kernel_mapper = KernelMapper::lock(); 5377799ccaSWu Mianzhi let kernel_mapper = kernel_mapper.as_mut().unwrap(); 5477799ccaSWu Mianzhi let flusher = kernel_mapper 5577799ccaSWu Mianzhi .remap(vaddr, kernel_page_flags(vaddr)) 5677799ccaSWu Mianzhi .expect("e1000e: remap failed"); 5777799ccaSWu Mianzhi flusher.flush(); 5877799ccaSWu Mianzhi 5977799ccaSWu Mianzhi unsafe { 6077799ccaSWu Mianzhi deallocate_page_frames(PhysPageFrame::new(PhysAddr::new(paddr)), page_count); 6177799ccaSWu Mianzhi } 6277799ccaSWu Mianzhi return 0; 6377799ccaSWu Mianzhi } 64