140fe15e0SLoGin use crate::arch::mm::kernel_page_flags; 240fe15e0SLoGin 340fe15e0SLoGin use crate::arch::MMArch; 440fe15e0SLoGin 540fe15e0SLoGin use crate::mm::kernel_mapper::KernelMapper; 66fc066acSJomo use crate::mm::page::{page_manager_lock_irqsave, PageFlags}; 740fe15e0SLoGin use crate::mm::{ 840fe15e0SLoGin allocator::page_frame::{ 940fe15e0SLoGin allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame, 1040fe15e0SLoGin }, 1140fe15e0SLoGin MemoryManagementArch, PhysAddr, VirtAddr, 1226d84a31SYJwu2023 }; 13004e86ffSlogin use core::ptr::NonNull; 1440fe15e0SLoGin use virtio_drivers::{BufferDirection, Hal, PAGE_SIZE}; 1540fe15e0SLoGin 1626d84a31SYJwu2023 pub struct HalImpl; 1713776c11Slogin unsafe impl Hal for HalImpl { 1826d84a31SYJwu2023 /// @brief 申请用于DMA的内存页 1926d84a31SYJwu2023 /// @param pages 页数(4k一页) 2026d84a31SYJwu2023 /// @return PhysAddr 获得的内存页的初始物理地址 2140fe15e0SLoGin fn dma_alloc( 2240fe15e0SLoGin pages: usize, 2340fe15e0SLoGin _direction: BufferDirection, 2440fe15e0SLoGin ) -> (virtio_drivers::PhysAddr, NonNull<u8>) { 2540fe15e0SLoGin let page_num = PageFrameCount::new( 2640fe15e0SLoGin ((pages * PAGE_SIZE + MMArch::PAGE_SIZE - 1) / MMArch::PAGE_SIZE).next_power_of_two(), 2740fe15e0SLoGin ); 2826d84a31SYJwu2023 unsafe { 2940fe15e0SLoGin let (paddr, count) = 3040fe15e0SLoGin allocate_page_frames(page_num).expect("VirtIO Impl: alloc page failed"); 3140fe15e0SLoGin let virt = MMArch::phys_2_virt(paddr).unwrap(); 3240fe15e0SLoGin // 清空这块区域,防止出现脏数据 3340fe15e0SLoGin core::ptr::write_bytes(virt.data() as *mut u8, 0, count.data() * MMArch::PAGE_SIZE); 3440fe15e0SLoGin 3540fe15e0SLoGin let dma_flags: PageFlags<MMArch> = PageFlags::mmio_flags(); 3640fe15e0SLoGin 3740fe15e0SLoGin let mut kernel_mapper = KernelMapper::lock(); 3840fe15e0SLoGin let kernel_mapper = kernel_mapper.as_mut().unwrap(); 3940fe15e0SLoGin let flusher = kernel_mapper 4040fe15e0SLoGin .remap(virt, dma_flags) 4140fe15e0SLoGin .expect("VirtIO Impl: remap failed"); 4240fe15e0SLoGin flusher.flush(); 4340fe15e0SLoGin return ( 4440fe15e0SLoGin paddr.data(), 4540fe15e0SLoGin NonNull::new(MMArch::phys_2_virt(paddr).unwrap().data() as _).unwrap(), 4640fe15e0SLoGin ); 4726d84a31SYJwu2023 } 4826d84a31SYJwu2023 } 4926d84a31SYJwu2023 /// @brief 释放用于DMA的内存页 5026d84a31SYJwu2023 /// @param paddr 起始物理地址 pages 页数(4k一页) 5126d84a31SYJwu2023 /// @return i32 0表示成功 5240fe15e0SLoGin unsafe fn dma_dealloc( 5340fe15e0SLoGin paddr: virtio_drivers::PhysAddr, 5440fe15e0SLoGin vaddr: NonNull<u8>, 5540fe15e0SLoGin pages: usize, 5640fe15e0SLoGin ) -> i32 { 5740fe15e0SLoGin let page_count = PageFrameCount::new( 5840fe15e0SLoGin ((pages * PAGE_SIZE + MMArch::PAGE_SIZE - 1) / MMArch::PAGE_SIZE).next_power_of_two(), 5940fe15e0SLoGin ); 6040fe15e0SLoGin 6140fe15e0SLoGin // 恢复页面属性 62b5b571e0SLoGin let vaddr = VirtAddr::new(vaddr.as_ptr() as usize); 6340fe15e0SLoGin let mut kernel_mapper = KernelMapper::lock(); 6440fe15e0SLoGin let kernel_mapper = kernel_mapper.as_mut().unwrap(); 6540fe15e0SLoGin let flusher = kernel_mapper 6640fe15e0SLoGin .remap(vaddr, kernel_page_flags(vaddr)) 6740fe15e0SLoGin .expect("VirtIO Impl: remap failed"); 6840fe15e0SLoGin flusher.flush(); 6940fe15e0SLoGin 7026d84a31SYJwu2023 unsafe { 7156cc4dbeSJomo deallocate_page_frames( 7256cc4dbeSJomo PhysPageFrame::new(PhysAddr::new(paddr)), 7356cc4dbeSJomo page_count, 746fc066acSJomo &mut page_manager_lock_irqsave(), 7556cc4dbeSJomo ); 7626d84a31SYJwu2023 } 7726d84a31SYJwu2023 return 0; 7826d84a31SYJwu2023 } 7973c607aaSYJwu2023 /// @brief mmio物理地址转换为虚拟地址,不需要使用 8026d84a31SYJwu2023 /// @param paddr 起始物理地址 8173c607aaSYJwu2023 /// @return NonNull<u8> 虚拟地址的指针 82*731bc2b3SLoGin unsafe fn mmio_phys_to_virt(paddr: virtio_drivers::PhysAddr, _size: usize) -> NonNull<u8> { 83*731bc2b3SLoGin NonNull::new((MMArch::phys_2_virt(PhysAddr::new(paddr))).unwrap().data() as _).unwrap() 8426d84a31SYJwu2023 } 8526d84a31SYJwu2023 /// @brief 与真实物理设备共享 8626d84a31SYJwu2023 /// @param buffer 要共享的buffer _direction:设备到driver或driver到设备 8726d84a31SYJwu2023 /// @return buffer在内存中的物理地址 8840fe15e0SLoGin unsafe fn share( 8940fe15e0SLoGin buffer: NonNull<[u8]>, 9040fe15e0SLoGin _direction: BufferDirection, 9140fe15e0SLoGin ) -> virtio_drivers::PhysAddr { 9240fe15e0SLoGin let vaddr = VirtAddr::new(buffer.as_ptr() as *mut u8 as usize); 9373c607aaSYJwu2023 //kdebug!("virt:{:x}", vaddr); 9426d84a31SYJwu2023 // Nothing to do, as the host already has access to all memory. 9540fe15e0SLoGin return MMArch::virt_2_phys(vaddr).unwrap().data(); 9626d84a31SYJwu2023 } 9726d84a31SYJwu2023 /// @brief 停止共享(让主机可以访问全部内存的话什么都不用做) 9840fe15e0SLoGin unsafe fn unshare( 9940fe15e0SLoGin _paddr: virtio_drivers::PhysAddr, 10040fe15e0SLoGin _buffer: NonNull<[u8]>, 10140fe15e0SLoGin _direction: BufferDirection, 10240fe15e0SLoGin ) { 10326d84a31SYJwu2023 // Nothing to do, as the host already has access to all memory and we didn't copy the buffer 10426d84a31SYJwu2023 // anywhere else. 10526d84a31SYJwu2023 } 10626d84a31SYJwu2023 } 107