Skip to main content

os/drivers/bus/
virtio.rs

1use crate::mm::{
2    FrameTracker, PageTable, PhysAddr, PhysPageNum, StepByOne, VirtAddr, frame_alloc_more,
3    frame_dealloc, kernel_token,
4};
5use crate::sync::UPIntrFreeCell;
6use alloc::vec::Vec;
7use lazy_static::*;
8use virtio_drivers::Hal;
9
10lazy_static! {
11    static ref QUEUE_FRAMES: UPIntrFreeCell<Vec<FrameTracker>> =
12        unsafe { UPIntrFreeCell::new(Vec::new()) };
13}
14
15pub struct VirtioHal;
16
17impl Hal for VirtioHal {
18    fn dma_alloc(pages: usize) -> usize {
19        let trakcers = frame_alloc_more(pages);
20        let ppn_base = trakcers.as_ref().unwrap().last().unwrap().ppn;
21        QUEUE_FRAMES
22            .exclusive_access()
23            .append(&mut trakcers.unwrap());
24        let pa: PhysAddr = ppn_base.into();
25        pa.0
26    }
27
28    fn dma_dealloc(pa: usize, pages: usize) -> i32 {
29        let pa = PhysAddr::from(pa);
30        let mut ppn_base: PhysPageNum = pa.into();
31        for _ in 0..pages {
32            frame_dealloc(ppn_base);
33            ppn_base.step();
34        }
35        0
36    }
37
38    fn phys_to_virt(addr: usize) -> usize {
39        addr
40    }
41
42    fn virt_to_phys(vaddr: usize) -> usize {
43        PageTable::from_token(kernel_token())
44            .translate_va(VirtAddr::from(vaddr))
45            .unwrap()
46            .0
47    }
48}