diff --git a/os/src/drivers/block/virtio_blk.rs b/os/src/drivers/block/virtio_blk.rs index ff460d75..2d853e0c 100644 --- a/os/src/drivers/block/virtio_blk.rs +++ b/os/src/drivers/block/virtio_blk.rs @@ -1,29 +1,19 @@ use super::BlockDevice; -use crate::mm::{ - frame_alloc, frame_dealloc, kernel_token, FrameTracker, PageTable, PhysAddr, PhysPageNum, - StepByOne, VirtAddr, -}; use crate::sync::{Condvar, UPIntrFreeCell}; use crate::task::schedule; use crate::DEV_NON_BLOCKING_ACCESS; use alloc::collections::BTreeMap; -use alloc::vec::Vec; -use lazy_static::*; use virtio_drivers::{BlkResp, RespStatus, VirtIOBlk, VirtIOHeader}; +use crate::drivers::bus::virtio::VirtioHal; #[allow(unused)] const VIRTIO0: usize = 0x10008000; pub struct VirtIOBlock { - virtio_blk: UPIntrFreeCell>, + virtio_blk: UPIntrFreeCell>, condvars: BTreeMap, } -lazy_static! { - static ref QUEUE_FRAMES: UPIntrFreeCell> = - unsafe { UPIntrFreeCell::new(Vec::new()) }; -} - impl BlockDevice for VirtIOBlock { fn read_block(&self, block_id: usize, buf: &mut [u8]) { let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access(); @@ -79,7 +69,7 @@ impl BlockDevice for VirtIOBlock { impl VirtIOBlock { pub fn new() -> Self { let virtio_blk = unsafe { - UPIntrFreeCell::new(VirtIOBlk::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap()) + UPIntrFreeCell::new(VirtIOBlk::::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap()) }; let mut condvars = BTreeMap::new(); let channels = virtio_blk.exclusive_access().virt_queue_size(); @@ -94,38 +84,3 @@ impl VirtIOBlock { } } -#[no_mangle] -pub extern "C" fn virtio_dma_alloc(pages: usize) -> PhysAddr { - let mut ppn_base = PhysPageNum(0); - for i in 0..pages { - let frame = frame_alloc().unwrap(); - if i == 0 { - ppn_base = frame.ppn; - } - assert_eq!(frame.ppn.0, ppn_base.0 + i); - QUEUE_FRAMES.exclusive_access().push(frame); - } - ppn_base.into() -} - -#[no_mangle] -pub extern "C" fn virtio_dma_dealloc(pa: PhysAddr, pages: usize) -> i32 { - let mut ppn_base: PhysPageNum = pa.into(); - for _ in 0..pages { - frame_dealloc(ppn_base); - ppn_base.step(); - } - 0 -} - -#[no_mangle] -pub extern "C" fn virtio_phys_to_virt(paddr: PhysAddr) -> VirtAddr { - VirtAddr(paddr.0) -} - -#[no_mangle] -pub extern "C" fn virtio_virt_to_phys(vaddr: VirtAddr) -> PhysAddr { - PageTable::from_token(kernel_token()) - .translate_va(vaddr) - .unwrap() -} diff --git a/os/src/drivers/bus/mod.rs b/os/src/drivers/bus/mod.rs new file mode 100644 index 00000000..ab8f38fd --- /dev/null +++ b/os/src/drivers/bus/mod.rs @@ -0,0 +1 @@ +pub mod virtio; \ No newline at end of file diff --git a/os/src/drivers/bus/virtio.rs b/os/src/drivers/bus/virtio.rs new file mode 100644 index 00000000..fe7bc127 --- /dev/null +++ b/os/src/drivers/bus/virtio.rs @@ -0,0 +1,52 @@ +use alloc::vec::Vec; +use crate::mm::{ + frame_alloc, frame_dealloc, kernel_token, FrameTracker, PageTable, PhysAddr, PhysPageNum, + StepByOne, VirtAddr, +}; +use crate::sync::UPIntrFreeCell; +use lazy_static::*; +use virtio_drivers::Hal; + +lazy_static! { + static ref QUEUE_FRAMES: UPIntrFreeCell> = + unsafe { UPIntrFreeCell::new(Vec::new()) }; +} + +pub struct VirtioHal; + +impl Hal for VirtioHal { + fn dma_alloc(pages: usize) -> usize { + let mut ppn_base = PhysPageNum(0); + for i in 0..pages { + let frame = frame_alloc().unwrap(); + if i == 0 { + ppn_base = frame.ppn; + } + assert_eq!(frame.ppn.0, ppn_base.0 + i); + QUEUE_FRAMES.exclusive_access().push(frame); + } + let pa: PhysAddr = ppn_base.into(); + pa.0 + } + + fn dma_dealloc(pa: usize, pages: usize) -> i32 { + let pa = PhysAddr::from(pa); + let mut ppn_base: PhysPageNum = pa.into(); + for _ in 0..pages { + frame_dealloc(ppn_base); + ppn_base.step(); + } + 0 + } + + fn phys_to_virt(addr: usize) -> usize { + addr + } + + fn virt_to_phys(vaddr: usize) -> usize { + PageTable::from_token(kernel_token()) + .translate_va(VirtAddr::from(vaddr)) + .unwrap() + .0 + } +} \ No newline at end of file diff --git a/os/src/drivers/gpu/mod.rs b/os/src/drivers/gpu/mod.rs index 2dc80d48..29028213 100644 --- a/os/src/drivers/gpu/mod.rs +++ b/os/src/drivers/gpu/mod.rs @@ -4,6 +4,7 @@ use core::any::Any; use embedded_graphics::pixelcolor::Rgb888; use tinybmp::Bmp; use virtio_drivers::{VirtIOGpu, VirtIOHeader}; +use crate::drivers::bus::virtio::VirtioHal; const VIRTIO7: usize = 0x10007000; pub trait GPUDevice: Send + Sync + Any { fn update_cursor(&self); @@ -16,14 +17,14 @@ lazy_static::lazy_static!( ); pub struct VirtIOGPU { - gpu: UPIntrFreeCell>, + gpu: UPIntrFreeCell>, fb: &'static [u8], } static BMP_DATA: &[u8] = include_bytes!("../../assert/mouse.bmp"); impl VirtIOGPU { pub fn new() -> Self { unsafe { - let mut virtio = VirtIOGpu::new(&mut *(VIRTIO7 as *mut VirtIOHeader)).unwrap(); + let mut virtio = VirtIOGpu::::new(&mut *(VIRTIO7 as *mut VirtIOHeader)).unwrap(); let fbuffer = virtio.setup_framebuffer().unwrap(); let len = fbuffer.len(); diff --git a/os/src/drivers/input/mod.rs b/os/src/drivers/input/mod.rs index 0acb0345..1da66a6d 100644 --- a/os/src/drivers/input/mod.rs +++ b/os/src/drivers/input/mod.rs @@ -11,6 +11,7 @@ use embedded_graphics::{ }; use k210_hal::cache::Uncache; use virtio_drivers::{VirtIOHeader, VirtIOInput}; +use crate::drivers::bus::virtio::VirtioHal; use virtio_input_decoder::{Decoder, Key, KeyType}; use super::GPU_DEVICE; @@ -18,7 +19,7 @@ use super::GPU_DEVICE; const VIRTIO5: usize = 0x10005000; const VIRTIO6: usize = 0x10006000; -struct VirtIOINPUT(UPIntrFreeCell>); +struct VirtIOINPUT(UPIntrFreeCell>); pub trait INPUTDevice: Send + Sync + Any { fn handle_irq(&self); @@ -32,7 +33,7 @@ lazy_static::lazy_static!( impl VirtIOINPUT { pub fn new(addr: usize) -> Self { Self(unsafe { - UPIntrFreeCell::new(VirtIOInput::new(&mut *(addr as *mut VirtIOHeader)).unwrap()) + UPIntrFreeCell::new(VirtIOInput::::new(&mut *(addr as *mut VirtIOHeader)).unwrap()) }) } } diff --git a/os/src/drivers/mod.rs b/os/src/drivers/mod.rs index 4ecf8a9d..cdd37574 100644 --- a/os/src/drivers/mod.rs +++ b/os/src/drivers/mod.rs @@ -4,6 +4,8 @@ pub mod chardev; pub mod gpu; #[cfg(feature = "board_qemu")] pub mod input; +#[cfg(feature = "board_qemu")] +pub mod bus; pub mod plic; pub use block::BLOCK_DEVICE; #[cfg(feature = "board_qemu")] @@ -12,3 +14,5 @@ pub use chardev::UART; pub use gpu::*; #[cfg(feature = "board_qemu")] pub use input::*; +#[cfg(feature = "board_qemu")] +pub use bus::*;