mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 00:43:24 +00:00
Refactor Virtio
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
df42397cea
commit
7d5e67e368
@ -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"
|
||||
|
@ -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()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user