xref: /DragonOS/kernel/src/driver/virtio/virtio_impl.rs (revision 73c607aaddf6e4634cad179a81d3f1bc589f7220)
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