# hal.rs - source
Source of the Rust file `/home/runner/.cargo/git/checkouts/virtio-drivers-4fdfaa862bcdc399/f30d426/src/hal.rs`.
Keywords: rust, rustlang, rust-lang

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62

    use super::*;

    type VirtAddr = usize;
    type PhysAddr = usize;

    pub struct DMA {
        paddr: u32,
        pages: u32,
    }

    impl DMA {
        pub fn new(pages: usize) -> Result<Self> {
            let paddr = unsafe { virtio_dma_alloc(pages) };
            if paddr == 0 {
                return Err(Error::DmaError);
            }
            Ok(DMA {
                paddr: paddr as u32,
                pages: pages as u32,
            })
        }

        pub fn paddr(&self) -> usize {
            self.paddr as usize
        }

        pub fn vaddr(&self) -> usize {
            phys_to_virt(self.paddr as usize)
        }

        /// Page frame number
        pub fn pfn(&self) -> u32 {
            self.paddr >> 12
        }

        /// Convert to a buffer
        pub unsafe fn as_buf(&self) -> &'static mut [u8] {
            core::slice::from_raw_parts_mut(self.vaddr() as _, PAGE_SIZE * self.pages as usize)
        }
    }

    impl Drop for DMA {
        fn drop(&mut self) {
            let err = unsafe { virtio_dma_dealloc(self.paddr as usize, self.pages as usize) };
            assert_eq!(err, 0, "failed to deallocate DMA");
        }
    }

    pub fn phys_to_virt(paddr: PhysAddr) -> VirtAddr {
        unsafe { virtio_phys_to_virt(paddr) }
    }

    pub fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr {
        unsafe { virtio_virt_to_phys(vaddr) }
    }

    extern "C" {
        fn virtio_dma_alloc(pages: usize) -> PhysAddr;
        fn virtio_dma_dealloc(paddr: PhysAddr, pages: usize) -> i32;
        fn virtio_phys_to_virt(paddr: PhysAddr) -> VirtAddr;
        fn virtio_virt_to_phys(vaddr: VirtAddr) -> PhysAddr;
    }