1*73c607aaSYJwu2023 /// 为virtio-drivers库提供的操作系统接口 226d84a31SYJwu2023 use crate::include::bindings::bindings::{ 326d84a31SYJwu2023 alloc_pages, free_pages, memory_management_struct, Page, PAGE_2M_SHIFT, PAGE_2M_SIZE, 426d84a31SYJwu2023 PAGE_OFFSET, PAGE_SHARED, ZONE_NORMAL, 526d84a31SYJwu2023 }; 6004e86ffSlogin 7*73c607aaSYJwu2023 use crate::mm::virt_2_phys; 826d84a31SYJwu2023 use core::mem::size_of; 9004e86ffSlogin use core::ptr::NonNull; 10*73c607aaSYJwu2023 use virtio_drivers::{BufferDirection, Hal, PhysAddr, PAGE_SIZE}; 1126d84a31SYJwu2023 pub struct HalImpl; 1226d84a31SYJwu2023 impl Hal for HalImpl { 1326d84a31SYJwu2023 /// @brief 申请用于DMA的内存页 1426d84a31SYJwu2023 /// @param pages 页数(4k一页) 1526d84a31SYJwu2023 /// @return PhysAddr 获得的内存页的初始物理地址 16*73c607aaSYJwu2023 fn dma_alloc(pages: usize, _direction: BufferDirection) -> (PhysAddr, NonNull<u8>) { 17*73c607aaSYJwu2023 let page_num = (pages * PAGE_SIZE - 1 + PAGE_2M_SIZE as usize) / PAGE_2M_SIZE as usize; 1826d84a31SYJwu2023 unsafe { 19*73c607aaSYJwu2023 let pa = alloc_pages(ZONE_NORMAL, page_num as i32, PAGE_SHARED as u64); 2026d84a31SYJwu2023 let page = *pa; 21*73c607aaSYJwu2023 //kdebug!("alloc pages num:{},Phyaddr={:#x}",pages,page.addr_phys); 22*73c607aaSYJwu2023 ( 23*73c607aaSYJwu2023 page.addr_phys as PhysAddr, 24*73c607aaSYJwu2023 NonNull::new((page.addr_phys as PhysAddr + PAGE_OFFSET as usize) as _).unwrap(), 25*73c607aaSYJwu2023 ) 2626d84a31SYJwu2023 } 2726d84a31SYJwu2023 } 2826d84a31SYJwu2023 /// @brief 释放用于DMA的内存页 2926d84a31SYJwu2023 /// @param paddr 起始物理地址 pages 页数(4k一页) 3026d84a31SYJwu2023 /// @return i32 0表示成功 31*73c607aaSYJwu2023 fn dma_dealloc(paddr: PhysAddr, _vaddr: NonNull<u8>, pages: usize) -> i32 { 32*73c607aaSYJwu2023 let page_num = (pages * PAGE_SIZE - 1 + PAGE_2M_SIZE as usize) / PAGE_2M_SIZE as usize; 3326d84a31SYJwu2023 unsafe { 3426d84a31SYJwu2023 let pa = (memory_management_struct.pages_struct as usize 3526d84a31SYJwu2023 + (paddr >> PAGE_2M_SHIFT) * size_of::<Page>()) as *mut Page; 3626d84a31SYJwu2023 //kdebug!("free pages num:{},Phyaddr={}",page_num,paddr); 37*73c607aaSYJwu2023 free_pages(pa, page_num as i32); 3826d84a31SYJwu2023 } 3926d84a31SYJwu2023 return 0; 4026d84a31SYJwu2023 } 41*73c607aaSYJwu2023 /// @brief mmio物理地址转换为虚拟地址,不需要使用 4226d84a31SYJwu2023 /// @param paddr 起始物理地址 43*73c607aaSYJwu2023 /// @return NonNull<u8> 虚拟地址的指针 44*73c607aaSYJwu2023 fn mmio_phys_to_virt(_paddr: PhysAddr, _size: usize) -> NonNull<u8> { 45*73c607aaSYJwu2023 NonNull::new((0) as _).unwrap() 4626d84a31SYJwu2023 } 4726d84a31SYJwu2023 /// @brief 与真实物理设备共享 4826d84a31SYJwu2023 /// @param buffer 要共享的buffer _direction:设备到driver或driver到设备 4926d84a31SYJwu2023 /// @return buffer在内存中的物理地址 5026d84a31SYJwu2023 fn share(buffer: NonNull<[u8]>, _direction: BufferDirection) -> PhysAddr { 5126d84a31SYJwu2023 let vaddr = buffer.as_ptr() as *mut u8 as usize; 52*73c607aaSYJwu2023 //kdebug!("virt:{:x}", vaddr); 5326d84a31SYJwu2023 // Nothing to do, as the host already has access to all memory. 54*73c607aaSYJwu2023 virt_2_phys(vaddr) 5526d84a31SYJwu2023 } 5626d84a31SYJwu2023 /// @brief 停止共享(让主机可以访问全部内存的话什么都不用做) 5726d84a31SYJwu2023 fn unshare(_paddr: PhysAddr, _buffer: NonNull<[u8]>, _direction: BufferDirection) { 5826d84a31SYJwu2023 // Nothing to do, as the host already has access to all memory and we didn't copy the buffer 5926d84a31SYJwu2023 // anywhere else. 6026d84a31SYJwu2023 } 6126d84a31SYJwu2023 } 62