Refactor Virtio

This commit is contained in:
Yuke Peng
2023-08-28 15:03:28 +08:00
committed by Tate, Hongliang Tian
parent df42397cea
commit 7d5e67e368
37 changed files with 1471 additions and 1413 deletions

View File

@ -9,7 +9,6 @@ edition = "2021"
bitflags = "1.3"
spin = "0.9.4"
jinux-frame = { path = "../../../framework/jinux-frame" }
jinux-virtio = { path = "../virtio" }
jinux-util = { path = "../../libs/jinux-util" }
component = { path = "../../libs/comp-sys/component" }
log = "0.4"

View File

@ -1,72 +1,65 @@
//! The block device of jinux
//! The block devices of jinux
#![no_std]
#![forbid(unsafe_code)]
#![feature(fn_traits)]
mod virtio;
extern crate alloc;
use core::any::Any;
use core::fmt::Debug;
use alloc::string::ToString;
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::sync::Arc;
use alloc::vec::Vec;
use component::init_component;
use component::ComponentInitError;
use jinux_virtio::VirtioDeviceType;
use jinux_frame::sync::SpinLock;
use spin::Once;
use virtio::VirtioBlockDevice;
pub const BLK_SIZE: usize = 512;
pub trait BlockDevice: Send + Sync + Any {
fn init(&self) {}
pub trait BlockDevice: Send + Sync + Any + Debug {
fn read_block(&self, block_id: usize, buf: &mut [u8]);
fn write_block(&self, block_id: usize, buf: &[u8]);
fn handle_irq(&self);
}
pub static BLK_COMPONENT: Once<BLKComponent> = Once::new();
pub fn register_device(name: String, device: Arc<dyn BlockDevice>) {
COMPONENT.get().unwrap().devices.lock().insert(name, device);
}
pub fn get_device(str: &String) -> Option<Arc<dyn BlockDevice>> {
COMPONENT.get().unwrap().devices.lock().get(str).cloned()
}
pub fn all_devices() -> Vec<(String, Arc<dyn BlockDevice>)> {
let lock = COMPONENT.get().unwrap().devices.lock();
let mut vec = Vec::new();
for (name, device) in lock.iter() {
vec.push((name.clone(), device.clone()));
}
vec
}
static COMPONENT: Once<Component> = Once::new();
#[init_component]
fn blk_component_init() -> Result<(), ComponentInitError> {
let a = BLKComponent::init()?;
BLK_COMPONENT.call_once(|| a);
fn component_init() -> Result<(), ComponentInitError> {
let a = Component::init()?;
COMPONENT.call_once(|| a);
Ok(())
}
pub struct BLKComponent {
/// Input device map, key is the irq number, value is the Input device
blk_device: Arc<dyn BlockDevice>,
#[derive(Debug)]
struct Component {
devices: SpinLock<BTreeMap<String, Arc<dyn BlockDevice>>>,
}
impl BLKComponent {
impl Component {
pub fn init() -> Result<Self, ComponentInitError> {
let virtio = jinux_virtio::VIRTIO_COMPONENT.get().unwrap();
let devices = virtio.get_device(VirtioDeviceType::Block);
// FIXME: deal with multiple block devices
if let Some(device) = devices.into_iter().next() {
let v_device = VirtioBlockDevice::new(device);
return Ok(Self {
blk_device: Arc::new(v_device),
});
}
Err(ComponentInitError::UninitializedDependencies(
"Virtio".to_string(),
))
}
pub const fn name() -> &'static str {
"Block device"
}
// 0~65535
pub const fn priority() -> u16 {
8192
}
}
impl BLKComponent {
pub fn get_device(self: &Self) -> Arc<dyn BlockDevice> {
self.blk_device.clone()
Ok(Self {
devices: SpinLock::new(BTreeMap::new()),
})
}
}

View File

@ -1,54 +0,0 @@
//! Block device based on Virtio
use jinux_frame::sync::Mutex;
use jinux_frame::{io_mem::IoMem, trap::TrapFrame};
use jinux_pci::msix::MSIX;
use jinux_util::safe_ptr::SafePtr;
use jinux_virtio::{device::block::device::BLKDevice, PCIVirtioDevice, VirtioPciCommonCfg};
use log::debug;
use crate::{BlockDevice, BLK_COMPONENT};
pub struct VirtioBlockDevice {
blk_device: Mutex<BLKDevice>,
pub common_cfg: SafePtr<VirtioPciCommonCfg, IoMem>,
_msix: MSIX,
}
impl BlockDevice for VirtioBlockDevice {
fn read_block(&self, block_id: usize, buf: &mut [u8]) {
self.blk_device.lock().read_block(block_id, buf);
}
/// it is blocking now
fn write_block(&self, block_id: usize, buf: &[u8]) {
self.blk_device.lock().write_block(block_id, buf);
}
fn handle_irq(&self) {
debug!("block device handle irq");
}
}
impl VirtioBlockDevice {
pub(crate) fn new(mut virtio_device: PCIVirtioDevice) -> Self {
fn handle_block_device(_: &TrapFrame) {
BLK_COMPONENT.get().unwrap().blk_device.handle_irq()
}
fn config_space_change(_: &TrapFrame) {
debug!("block device config space change");
}
virtio_device.register_interrupt_functions(&config_space_change, &handle_block_device);
let blk_device = Mutex::new(match virtio_device.device {
jinux_virtio::device::VirtioDevice::Block(blk) => blk,
_ => {
panic!("Error when creating new block device, the input device is other type of virtio device");
}
});
Self {
blk_device,
common_cfg: virtio_device.common_cfg,
_msix: virtio_device.msix,
}
}
}