This commit is contained in:
Yifan Wu 2022-09-02 02:54:55 -07:00
parent 25f4e37168
commit 25a398adc2
6 changed files with 66 additions and 52 deletions

View file

@ -1,29 +1,19 @@
use super::BlockDevice; 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::sync::{Condvar, UPIntrFreeCell};
use crate::task::schedule; use crate::task::schedule;
use crate::DEV_NON_BLOCKING_ACCESS; use crate::DEV_NON_BLOCKING_ACCESS;
use alloc::collections::BTreeMap; use alloc::collections::BTreeMap;
use alloc::vec::Vec;
use lazy_static::*;
use virtio_drivers::{BlkResp, RespStatus, VirtIOBlk, VirtIOHeader}; use virtio_drivers::{BlkResp, RespStatus, VirtIOBlk, VirtIOHeader};
use crate::drivers::bus::virtio::VirtioHal;
#[allow(unused)] #[allow(unused)]
const VIRTIO0: usize = 0x10008000; const VIRTIO0: usize = 0x10008000;
pub struct VirtIOBlock { pub struct VirtIOBlock {
virtio_blk: UPIntrFreeCell<VirtIOBlk<'static>>, virtio_blk: UPIntrFreeCell<VirtIOBlk<'static, VirtioHal>>,
condvars: BTreeMap<u16, Condvar>, condvars: BTreeMap<u16, Condvar>,
} }
lazy_static! {
static ref QUEUE_FRAMES: UPIntrFreeCell<Vec<FrameTracker>> =
unsafe { UPIntrFreeCell::new(Vec::new()) };
}
impl BlockDevice for VirtIOBlock { impl BlockDevice for VirtIOBlock {
fn read_block(&self, block_id: usize, buf: &mut [u8]) { fn read_block(&self, block_id: usize, buf: &mut [u8]) {
let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access(); let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access();
@ -79,7 +69,7 @@ impl BlockDevice for VirtIOBlock {
impl VirtIOBlock { impl VirtIOBlock {
pub fn new() -> Self { pub fn new() -> Self {
let virtio_blk = unsafe { let virtio_blk = unsafe {
UPIntrFreeCell::new(VirtIOBlk::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap()) UPIntrFreeCell::new(VirtIOBlk::<VirtioHal>::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap())
}; };
let mut condvars = BTreeMap::new(); let mut condvars = BTreeMap::new();
let channels = virtio_blk.exclusive_access().virt_queue_size(); 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()
}

View file

@ -0,0 +1 @@
pub mod virtio;

View file

@ -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<Vec<FrameTracker>> =
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
}
}

View file

@ -4,6 +4,7 @@ use core::any::Any;
use embedded_graphics::pixelcolor::Rgb888; use embedded_graphics::pixelcolor::Rgb888;
use tinybmp::Bmp; use tinybmp::Bmp;
use virtio_drivers::{VirtIOGpu, VirtIOHeader}; use virtio_drivers::{VirtIOGpu, VirtIOHeader};
use crate::drivers::bus::virtio::VirtioHal;
const VIRTIO7: usize = 0x10007000; const VIRTIO7: usize = 0x10007000;
pub trait GPUDevice: Send + Sync + Any { pub trait GPUDevice: Send + Sync + Any {
fn update_cursor(&self); fn update_cursor(&self);
@ -16,14 +17,14 @@ lazy_static::lazy_static!(
); );
pub struct VirtIOGPU { pub struct VirtIOGPU {
gpu: UPIntrFreeCell<VirtIOGpu<'static>>, gpu: UPIntrFreeCell<VirtIOGpu<'static, VirtioHal>>,
fb: &'static [u8], fb: &'static [u8],
} }
static BMP_DATA: &[u8] = include_bytes!("../../assert/mouse.bmp"); static BMP_DATA: &[u8] = include_bytes!("../../assert/mouse.bmp");
impl VirtIOGPU { impl VirtIOGPU {
pub fn new() -> Self { pub fn new() -> Self {
unsafe { unsafe {
let mut virtio = VirtIOGpu::new(&mut *(VIRTIO7 as *mut VirtIOHeader)).unwrap(); let mut virtio = VirtIOGpu::<VirtioHal>::new(&mut *(VIRTIO7 as *mut VirtIOHeader)).unwrap();
let fbuffer = virtio.setup_framebuffer().unwrap(); let fbuffer = virtio.setup_framebuffer().unwrap();
let len = fbuffer.len(); let len = fbuffer.len();

View file

@ -11,6 +11,7 @@ use embedded_graphics::{
}; };
use k210_hal::cache::Uncache; use k210_hal::cache::Uncache;
use virtio_drivers::{VirtIOHeader, VirtIOInput}; use virtio_drivers::{VirtIOHeader, VirtIOInput};
use crate::drivers::bus::virtio::VirtioHal;
use virtio_input_decoder::{Decoder, Key, KeyType}; use virtio_input_decoder::{Decoder, Key, KeyType};
use super::GPU_DEVICE; use super::GPU_DEVICE;
@ -18,7 +19,7 @@ use super::GPU_DEVICE;
const VIRTIO5: usize = 0x10005000; const VIRTIO5: usize = 0x10005000;
const VIRTIO6: usize = 0x10006000; const VIRTIO6: usize = 0x10006000;
struct VirtIOINPUT(UPIntrFreeCell<VirtIOInput<'static>>); struct VirtIOINPUT(UPIntrFreeCell<VirtIOInput<'static, VirtioHal>>);
pub trait INPUTDevice: Send + Sync + Any { pub trait INPUTDevice: Send + Sync + Any {
fn handle_irq(&self); fn handle_irq(&self);
@ -32,7 +33,7 @@ lazy_static::lazy_static!(
impl VirtIOINPUT { impl VirtIOINPUT {
pub fn new(addr: usize) -> Self { pub fn new(addr: usize) -> Self {
Self(unsafe { Self(unsafe {
UPIntrFreeCell::new(VirtIOInput::new(&mut *(addr as *mut VirtIOHeader)).unwrap()) UPIntrFreeCell::new(VirtIOInput::<VirtioHal>::new(&mut *(addr as *mut VirtIOHeader)).unwrap())
}) })
} }
} }

View file

@ -4,6 +4,8 @@ pub mod chardev;
pub mod gpu; pub mod gpu;
#[cfg(feature = "board_qemu")] #[cfg(feature = "board_qemu")]
pub mod input; pub mod input;
#[cfg(feature = "board_qemu")]
pub mod bus;
pub mod plic; pub mod plic;
pub use block::BLOCK_DEVICE; pub use block::BLOCK_DEVICE;
#[cfg(feature = "board_qemu")] #[cfg(feature = "board_qemu")]
@ -12,3 +14,5 @@ pub use chardev::UART;
pub use gpu::*; pub use gpu::*;
#[cfg(feature = "board_qemu")] #[cfg(feature = "board_qemu")]
pub use input::*; pub use input::*;
#[cfg(feature = "board_qemu")]
pub use bus::*;