Fix typos and add utils

This commit is contained in:
Jianfeng Jiang
2023-05-31 10:46:51 +08:00
committed by Tate, Hongliang Tian
parent b2f2c55c9b
commit d96fe31e36
26 changed files with 388 additions and 71 deletions

View File

@ -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,
}

View File

@ -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 {

View File

@ -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" }

View File

@ -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));
}

View File

@ -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>,

View File

@ -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),

View File

@ -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() {

View File

@ -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