Merged PR #87
This commit is contained in:
parent
25f4e37168
commit
25a398adc2
6 changed files with 66 additions and 52 deletions
|
@ -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()
|
|
||||||
}
|
|
||||||
|
|
1
os/src/drivers/bus/mod.rs
Normal file
1
os/src/drivers/bus/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod virtio;
|
52
os/src/drivers/bus/virtio.rs
Normal file
52
os/src/drivers/bus/virtio.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
|
|
@ -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())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue