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}