mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-27 19:33:23 +00:00
Fix typos and add utils
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
b2f2c55c9b
commit
d96fe31e36
@ -3,7 +3,7 @@
|
||||
use jinux_frame::trap::TrapFrame;
|
||||
use jinux_pci::msix::MSIX;
|
||||
use jinux_util::frame_ptr::InFramePtr;
|
||||
use jinux_virtio::{device::block::device::BLKDevice, PCIVirtioDevice, VitrioPciCommonCfg};
|
||||
use jinux_virtio::{device::block::device::BLKDevice, PCIVirtioDevice, VirtioPciCommonCfg};
|
||||
use log::debug;
|
||||
use spin::Mutex;
|
||||
|
||||
@ -11,7 +11,7 @@ use crate::{BlockDevice, BLK_COMPONENT};
|
||||
|
||||
pub struct VirtioBlockDevice {
|
||||
blk_device: Mutex<BLKDevice>,
|
||||
pub common_cfg: InFramePtr<VitrioPciCommonCfg>,
|
||||
pub common_cfg: InFramePtr<VirtioPciCommonCfg>,
|
||||
msix: MSIX,
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use jinux_frame::trap::TrapFrame;
|
||||
use jinux_pci::msix::MSIX;
|
||||
use jinux_util::frame_ptr::InFramePtr;
|
||||
use jinux_virtio::device::input::device::InputProp;
|
||||
use jinux_virtio::VitrioPciCommonCfg;
|
||||
use jinux_virtio::VirtioPciCommonCfg;
|
||||
use jinux_virtio::{
|
||||
device::input::{device::InputDevice, InputConfigSelect},
|
||||
PCIVirtioDevice,
|
||||
@ -18,7 +18,7 @@ use virtio_input_decoder::{DecodeType, Decoder};
|
||||
use crate::INPUTDevice;
|
||||
pub struct VirtioInputDevice {
|
||||
input_device: InputDevice,
|
||||
common_cfg: InFramePtr<VitrioPciCommonCfg>,
|
||||
common_cfg: InFramePtr<VirtioPciCommonCfg>,
|
||||
msix: Mutex<MSIX>,
|
||||
name: String,
|
||||
callbacks: Mutex<Vec<Arc<dyn Fn(DecodeType) + Send + Sync + 'static>>>,
|
||||
@ -57,7 +57,7 @@ impl VirtioInputDevice {
|
||||
let mut msix = virtio_device.msix;
|
||||
|
||||
let config_msix_vector =
|
||||
common_cfg.read_at(offset_of!(VitrioPciCommonCfg, config_msix_vector)) as usize;
|
||||
common_cfg.read_at(offset_of!(VirtioPciCommonCfg, config_msix_vector)) as usize;
|
||||
|
||||
let mut event_irq_number = 0;
|
||||
for i in 0..msix.table_size as usize {
|
||||
|
@ -8,6 +8,7 @@ edition = "2021"
|
||||
[dependencies]
|
||||
bitflags = "1.3"
|
||||
spin = "0.9.4"
|
||||
align_ext = { path = "../../../framework/libs/align_ext" }
|
||||
jinux-frame = { path = "../../../framework/jinux-frame" }
|
||||
jinux-pci = { path = "../pci" }
|
||||
jinux-util = { path = "../../libs/jinux-util" }
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
||||
device::block::{BlkReq, BlkResp, ReqType, RespStatus, BLK_SIZE},
|
||||
device::VirtioDeviceError,
|
||||
queue::{QueueError, VirtQueue},
|
||||
VitrioPciCommonCfg,
|
||||
VirtioPciCommonCfg,
|
||||
};
|
||||
|
||||
use super::{BLKFeatures, VirtioBLKConfig};
|
||||
@ -27,13 +27,13 @@ impl BLKDevice {
|
||||
pub(crate) fn new(
|
||||
cap: &CapabilityVirtioData,
|
||||
bars: [Option<BAR>; 6],
|
||||
common_cfg: &InFramePtr<VitrioPciCommonCfg>,
|
||||
common_cfg: &InFramePtr<VirtioPciCommonCfg>,
|
||||
notify_base_address: usize,
|
||||
notify_off_multiplier: u32,
|
||||
mut msix_vector_left: Vec<u16>,
|
||||
) -> Result<Self, VirtioDeviceError> {
|
||||
let config = VirtioBLKConfig::new(cap, bars);
|
||||
let num_queues = common_cfg.read_at(offset_of!(VitrioPciCommonCfg, num_queues)) as u16;
|
||||
let num_queues = common_cfg.read_at(offset_of!(VirtioPciCommonCfg, num_queues)) as u16;
|
||||
if num_queues != 1 {
|
||||
return Err(VirtioDeviceError::QueuesAmountDoNotMatch(num_queues, 1));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{device::VirtioDeviceError, queue::VirtQueue, VitrioPciCommonCfg};
|
||||
use crate::{device::VirtioDeviceError, queue::VirtQueue, VirtioPciCommonCfg};
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
use bitflags::bitflags;
|
||||
use jinux_frame::offset_of;
|
||||
@ -56,7 +56,7 @@ impl InputDevice {
|
||||
pub fn new(
|
||||
cap: &CapabilityVirtioData,
|
||||
bars: [Option<BAR>; 6],
|
||||
common_cfg: &InFramePtr<VitrioPciCommonCfg>,
|
||||
common_cfg: &InFramePtr<VirtioPciCommonCfg>,
|
||||
notify_base_address: usize,
|
||||
notify_off_multiplier: u32,
|
||||
mut msix_vector_left: Vec<u16>,
|
||||
|
@ -1,4 +1,7 @@
|
||||
use crate::{device::block::device::BLKDevice, Feature, VirtioDeviceType, VitrioPciCommonCfg};
|
||||
use crate::{
|
||||
device::block::device::BLKDevice, queue::QueueError, Feature, VirtioDeviceType,
|
||||
VirtioPciCommonCfg,
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use jinux_pci::{
|
||||
capability::{vendor::virtio::CapabilityVirtioData, Capability},
|
||||
@ -43,11 +46,17 @@ pub enum VirtioDeviceError {
|
||||
CapabilityListError,
|
||||
}
|
||||
|
||||
impl From<QueueError> for VirtioDeviceError {
|
||||
fn from(_: QueueError) -> Self {
|
||||
VirtioDeviceError::QueueUnknownError
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VirtioInfo {
|
||||
pub device_type: VirtioDeviceType,
|
||||
pub notify_base_address: u64,
|
||||
pub notify_off_multiplier: u32,
|
||||
pub common_cfg_frame_ptr: InFramePtr<VitrioPciCommonCfg>,
|
||||
pub common_cfg_frame_ptr: InFramePtr<VirtioPciCommonCfg>,
|
||||
pub device_cap_cfg: CapabilityVirtioData,
|
||||
}
|
||||
|
||||
@ -68,7 +77,7 @@ impl VirtioInfo {
|
||||
match cap_data.cfg_type {
|
||||
PCI_VIRTIO_CAP_COMMON_CFG => {
|
||||
common_cfg_frame_ptr_some =
|
||||
Some(VitrioPciCommonCfg::new(&cap_data, bars));
|
||||
Some(VirtioPciCommonCfg::new(&cap_data, bars));
|
||||
}
|
||||
PCI_VIRTIO_CAP_NOTIFY_CFG => {
|
||||
notify_off_multiplier = cap_data.option.unwrap();
|
||||
@ -140,7 +149,8 @@ impl VirtioDevice {
|
||||
}
|
||||
|
||||
pub(crate) fn negotiate_features(features: u64, device_type: VirtioDeviceType) -> u64 {
|
||||
let device_specified_features = features & ((1 << 24) - 1);
|
||||
let mask = ((1u64 << 24) - 1) | (((1u64 << 24) - 1) << 50);
|
||||
let device_specified_features = features & mask;
|
||||
let device_support_features = match device_type {
|
||||
VirtioDeviceType::Network => todo!(),
|
||||
VirtioDeviceType::Block => BLKDevice::negotiate_features(device_specified_features),
|
||||
|
@ -119,7 +119,7 @@ bitflags! {
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// all device features, bits 0~23 are sepecified by device
|
||||
/// all device features, bits 0~23 and 50~63 are sepecified by device.
|
||||
/// if using this struct to translate u64, use from_bits_truncate function instead of from_bits
|
||||
///
|
||||
struct Feature: u64 {
|
||||
@ -144,7 +144,7 @@ bitflags! {
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct VitrioPciCommonCfg {
|
||||
pub struct VirtioPciCommonCfg {
|
||||
device_feature_select: u32,
|
||||
device_feature: u32,
|
||||
driver_feature_select: u32,
|
||||
@ -164,7 +164,7 @@ pub struct VitrioPciCommonCfg {
|
||||
queue_device: u64,
|
||||
}
|
||||
|
||||
impl VitrioPciCommonCfg {
|
||||
impl VirtioPciCommonCfg {
|
||||
pub(crate) fn new(cap: &CapabilityVirtioData, bars: [Option<BAR>; 6]) -> InFramePtr<Self> {
|
||||
let bar = cap.bar;
|
||||
let offset = cap.offset;
|
||||
@ -219,7 +219,7 @@ impl VirtioDeviceType {
|
||||
|
||||
pub struct PCIVirtioDevice {
|
||||
/// common config of one device
|
||||
pub common_cfg: InFramePtr<VitrioPciCommonCfg>,
|
||||
pub common_cfg: InFramePtr<VirtioPciCommonCfg>,
|
||||
pub device: VirtioDevice,
|
||||
pub msix: MSIX,
|
||||
}
|
||||
@ -269,35 +269,35 @@ impl PCIVirtioDevice {
|
||||
let common_cfg_frame_ptr = &virtio_info.common_cfg_frame_ptr;
|
||||
|
||||
// Reset device
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VitrioPciCommonCfg, device_status), 0 as u8);
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VirtioPciCommonCfg, device_status), 0 as u8);
|
||||
|
||||
let num_queues: u16 =
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VitrioPciCommonCfg, num_queues));
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VirtioPciCommonCfg, num_queues));
|
||||
debug!("num_queues:{:x}", num_queues);
|
||||
// the table size of msix should be equal to n+1 or 2 where n is the virtqueue amount
|
||||
assert!(msix.table_size == 2 || msix.table_size == (num_queues + 1));
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, config_msix_vector),
|
||||
offset_of!(VirtioPciCommonCfg, config_msix_vector),
|
||||
config_msix_vector,
|
||||
);
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, device_status),
|
||||
offset_of!(VirtioPciCommonCfg, device_status),
|
||||
(DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER).bits(),
|
||||
);
|
||||
// negotiate features
|
||||
// get the value of device features
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, device_feature_select),
|
||||
offset_of!(VirtioPciCommonCfg, device_feature_select),
|
||||
0 as u32,
|
||||
);
|
||||
let mut low: u32 =
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VitrioPciCommonCfg, device_feature));
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VirtioPciCommonCfg, device_feature));
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, device_feature_select),
|
||||
offset_of!(VirtioPciCommonCfg, device_feature_select),
|
||||
1 as u32,
|
||||
);
|
||||
let mut high: u32 =
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VitrioPciCommonCfg, device_feature));
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VirtioPciCommonCfg, device_feature));
|
||||
let mut feature = (high as u64) << 32;
|
||||
feature |= low as u64;
|
||||
// let the device to negotiate Features
|
||||
@ -307,26 +307,26 @@ impl PCIVirtioDevice {
|
||||
low = driver_features as u32;
|
||||
high = (driver_features >> 32) as u32;
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, driver_feature_select),
|
||||
offset_of!(VirtioPciCommonCfg, driver_feature_select),
|
||||
0 as u32,
|
||||
);
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VitrioPciCommonCfg, driver_feature), low);
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VirtioPciCommonCfg, driver_feature), low);
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, driver_feature_select),
|
||||
offset_of!(VirtioPciCommonCfg, driver_feature_select),
|
||||
1 as u32,
|
||||
);
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VitrioPciCommonCfg, driver_feature), high);
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VirtioPciCommonCfg, driver_feature), high);
|
||||
|
||||
// change to features ok status
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, device_status),
|
||||
offset_of!(VirtioPciCommonCfg, device_status),
|
||||
(DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER | DeviceStatus::FEATURES_OK).bits(),
|
||||
);
|
||||
let device = VirtioDevice::new(&virtio_info, bars, msix_vector_list).unwrap();
|
||||
|
||||
// change to driver ok status
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, device_status),
|
||||
offset_of!(VirtioPciCommonCfg, device_status),
|
||||
(DeviceStatus::ACKNOWLEDGE
|
||||
| DeviceStatus::DRIVER
|
||||
| DeviceStatus::FEATURES_OK
|
||||
@ -351,7 +351,7 @@ impl PCIVirtioDevice {
|
||||
{
|
||||
let config_msix_vector =
|
||||
self.common_cfg
|
||||
.read_at(offset_of!(VitrioPciCommonCfg, config_msix_vector)) as usize;
|
||||
.read_at(offset_of!(VirtioPciCommonCfg, config_msix_vector)) as usize;
|
||||
for i in 0..self.msix.table_size as usize {
|
||||
let msix = self.msix.table.get_mut(i).unwrap();
|
||||
if !msix.irq_handle.is_empty() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Virtqueue
|
||||
|
||||
use super::VitrioPciCommonCfg;
|
||||
use super::VirtioPciCommonCfg;
|
||||
use alloc::vec::Vec;
|
||||
use bitflags::bitflags;
|
||||
use core::sync::atomic::{fence, Ordering};
|
||||
@ -55,29 +55,29 @@ pub struct VirtQueue {
|
||||
impl VirtQueue {
|
||||
/// Create a new VirtQueue.
|
||||
pub(crate) fn new(
|
||||
cfg: &InFramePtr<VitrioPciCommonCfg>,
|
||||
cfg: &InFramePtr<VirtioPciCommonCfg>,
|
||||
idx: usize,
|
||||
size: u16,
|
||||
notify_base_address: usize,
|
||||
notify_off_multiplier: u32,
|
||||
msix_vector: u16,
|
||||
) -> Result<Self, QueueError> {
|
||||
cfg.write_at(offset_of!(VitrioPciCommonCfg, queue_select), idx as u16);
|
||||
cfg.write_at(offset_of!(VirtioPciCommonCfg, queue_select), idx as u16);
|
||||
assert_eq!(
|
||||
cfg.read_at(offset_of!(VitrioPciCommonCfg, queue_select)),
|
||||
cfg.read_at(offset_of!(VirtioPciCommonCfg, queue_select)),
|
||||
idx as u16
|
||||
);
|
||||
if !size.is_power_of_two() {
|
||||
return Err(QueueError::InvalidArgs);
|
||||
}
|
||||
|
||||
cfg.write_at(offset_of!(VitrioPciCommonCfg, queue_size), size);
|
||||
cfg.write_at(offset_of!(VirtioPciCommonCfg, queue_size), size);
|
||||
cfg.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, queue_msix_vector),
|
||||
offset_of!(VirtioPciCommonCfg, queue_msix_vector),
|
||||
msix_vector,
|
||||
);
|
||||
assert_eq!(
|
||||
cfg.read_at(offset_of!(VitrioPciCommonCfg, queue_msix_vector)),
|
||||
cfg.read_at(offset_of!(VirtioPciCommonCfg, queue_msix_vector)),
|
||||
msix_vector
|
||||
);
|
||||
|
||||
@ -109,17 +109,17 @@ impl VirtQueue {
|
||||
debug!("queue_device start paddr:{:x?}", used_frame_ptr.paddr());
|
||||
|
||||
cfg.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, queue_desc),
|
||||
offset_of!(VirtioPciCommonCfg, queue_desc),
|
||||
desc_frame_ptr.paddr() as u64,
|
||||
);
|
||||
|
||||
cfg.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, queue_driver),
|
||||
offset_of!(VirtioPciCommonCfg, queue_driver),
|
||||
avail_frame_ptr.paddr() as u64,
|
||||
);
|
||||
|
||||
cfg.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, queue_device),
|
||||
offset_of!(VirtioPciCommonCfg, queue_device),
|
||||
used_frame_ptr.paddr() as u64,
|
||||
);
|
||||
|
||||
@ -137,7 +137,7 @@ impl VirtQueue {
|
||||
temp.write_at(offset_of!(Descriptor, next), i + 1);
|
||||
}
|
||||
avail_frame_ptr.write_at(offset_of!(AvailRing, flags), 0 as u16);
|
||||
cfg.write_at(offset_of!(VitrioPciCommonCfg, queue_enable), 1 as u16);
|
||||
cfg.write_at(offset_of!(VirtioPciCommonCfg, queue_enable), 1 as u16);
|
||||
Ok(VirtQueue {
|
||||
descs,
|
||||
avail: avail_frame_ptr,
|
||||
@ -305,6 +305,14 @@ impl VirtQueue {
|
||||
self.queue_size
|
||||
}
|
||||
|
||||
/// whether the driver should notify the device
|
||||
pub fn should_notify(&self) -> bool {
|
||||
// read barrier
|
||||
fence(Ordering::SeqCst);
|
||||
let flags = self.used.read_at(offset_of!(UsedRing, flags));
|
||||
flags & 0x0001u16 == 0u16
|
||||
}
|
||||
|
||||
/// notify that there are available rings
|
||||
pub fn notify(&mut self) {
|
||||
self.notify
|
||||
|
Reference in New Issue
Block a user