pci重构+pcie支持 (#235)

* pci重构+pcie支持

* pci重构测试完成

* 修正makefile的问题

* 小修改

* 修改函数名字
This commit is contained in:
YJwu2023 2023-04-09 12:30:02 +08:00 committed by GitHub
parent 5c9a63df83
commit 78bf93f02f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 1478 additions and 501 deletions

27
kernel/src/arch/mod.rs Normal file
View File

@ -0,0 +1,27 @@
pub mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use self::x86_64::pci::pci::X86_64PciArch as PciArch;
#[cfg(target_arch = "x86_64")]
pub use self::x86_64::*; //公开x86_64架构下的函数使外界接口统一
use crate::driver::pci::pci::{BusDeviceFunction, PciError, PciRoot, SegmentGroupNumber};
/// TraitPciArch Pci架构相关函数任何架构都应独立实现trait里的函数
pub trait TraitPciArch {
/// @brief 读取寄存器值x86_64架构通过读取两个特定io端口实现
/// @param bus_device_function 设备的唯一标识符
/// @param offset 寄存器偏移值
/// @return 读取到的值
fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32;
/// @brief 写入寄存器值x86_64架构通过读取两个特定io端口实现
/// @param bus_device_function 设备的唯一标识符
/// @param offset 寄存器偏移值
/// @param data 要写入的值
fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32);
/// @brief PCI域地址到存储器域地址的转换,x86_64架构为一一对应
/// @param address PCI域地址
/// @return Result<usize, PciError> 转换结果或出错原因
fn address_pci_to_address_memory(address: usize) -> Result<usize, PciError>;
/// @brief 获取Segement的root地址,x86_64架构为acpi mcfg表中读取
/// @param segement 组id
/// @return Result<PciRoot, PciError> 转换结果或出错原因
fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError>;
}

View File

@ -2,7 +2,7 @@ use crate::include::bindings::bindings::{process_control_block, switch_proc};
use core::sync::atomic::compiler_fence;
use super::fpu::{fp_state_save, fp_state_restore};
use super::fpu::{fp_state_restore, fp_state_save};
/// @brief 切换进程的上下文(没有切换页表的动作)
///

View File

@ -2,7 +2,8 @@
pub mod asm;
pub mod context;
pub mod cpu;
pub mod fpu;
pub mod interrupt;
pub mod mm;
pub mod pci;
pub mod sched;
pub mod fpu;

View File

@ -0,0 +1 @@
pub mod pci;

View File

@ -0,0 +1,70 @@
use crate::arch::TraitPciArch;
use crate::driver::acpi::acpi::mcfg_find_segment;
use crate::driver::pci::pci::{
BusDeviceFunction, PciError, PciRoot, SegmentGroupNumber, PORT_PCI_CONFIG_ADDRESS,
PORT_PCI_CONFIG_DATA,
};
use crate::include::bindings::bindings::{
acpi_get_MCFG, acpi_iter_SDT, acpi_system_description_table_header_t, io_in32, io_out32,
};
use core::ffi::c_void;
use core::ptr::NonNull;
pub struct X86_64PciArch {}
impl TraitPciArch for X86_64PciArch {
fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 {
// 构造pci配置空间地址
let address = ((bus_device_function.bus as u32) << 16)
| ((bus_device_function.device as u32) << 11)
| ((bus_device_function.function as u32 & 7) << 8)
| (offset & 0xfc) as u32
| (0x80000000);
let ret = unsafe {
io_out32(PORT_PCI_CONFIG_ADDRESS, address);
let temp = io_in32(PORT_PCI_CONFIG_DATA);
temp
};
return ret;
}
fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) {
let address = ((bus_device_function.bus as u32) << 16)
| ((bus_device_function.device as u32) << 11)
| ((bus_device_function.function as u32 & 7) << 8)
| (offset & 0xfc) as u32
| (0x80000000);
unsafe {
io_out32(PORT_PCI_CONFIG_ADDRESS, address);
// 写入数据
io_out32(PORT_PCI_CONFIG_DATA, data);
}
}
fn address_pci_to_address_memory(address: usize) -> Result<usize, PciError> {
Ok(address)
}
fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError> {
let mut data: usize = 0;
let data_point = &mut data;
unsafe {
acpi_iter_SDT(Some(acpi_get_MCFG), data_point as *mut usize as *mut c_void);
};
//kdebug!("{}",data);
//loop{}
let head = NonNull::new(data as *mut acpi_system_description_table_header_t).unwrap();
let outcome = unsafe { mcfg_find_segment(head).as_ref() };
for segmentgroupconfiguration in outcome {
if segmentgroupconfiguration.segement_group_number == segement {
return Ok(PciRoot {
physical_address_base: segmentgroupconfiguration.base_address,
mmio_base: None,
segement_group_number: segement,
bus_begin: segmentgroupconfiguration.bus_begin,
bus_end: segmentgroupconfiguration.bus_end,
});
}
}
return Err(PciError::SegmentNotFound);
}
}

View File

@ -1,7 +1,7 @@
CFLAGS += -I .
kernel_driver_subdirs:=video interrupt usb pci acpi disk keyboard mouse multiboot2 timers hid virtio
kernel_driver_subdirs:=video interrupt usb pci acpi disk keyboard mouse multiboot2 timers hid
ECHO:
@echo "$@"

View File

@ -103,6 +103,22 @@ bool acpi_get_HPET(const struct acpi_system_description_table_header_t *_iter_da
return true;
}
/**
* @brief MCFG MCFG_description_table
*
* @param _iter_data
* @param _data MCFG表的虚拟地址
* @return true
* @return false
*/
bool acpi_get_MCFG(const struct acpi_system_description_table_header_t *_iter_data, void *_data)
{
if (!(_iter_data->Signature[0] == 'M' && _iter_data->Signature[1] == 'C' && _iter_data->Signature[2] == 'F' && _iter_data->Signature[3] == 'G'))
return false;
*(ul *)_data = (ul)_iter_data;
return true;
}
/**
* @brief acpi模块
*

View File

@ -193,5 +193,14 @@ bool acpi_get_MADT(const struct acpi_system_description_table_header_t *_iter_da
*/
bool acpi_get_HPET(const struct acpi_system_description_table_header_t *_iter_data, void *_data);
/**
* @brief MCFG MCFG_description_table
*
* @param _iter_data
* @param _data MCFG表的虚拟地址
* @return true
* @return false
*/
bool acpi_get_MCFG(const struct acpi_system_description_table_header_t *_iter_data, void *_data);
// 初始化acpi模块
void acpi_init();

View File

@ -0,0 +1,27 @@
use crate::driver::pci::pci::SegmentGroupNumber;
use crate::include::bindings::bindings::acpi_system_description_table_header_t;
use core::ptr::{slice_from_raw_parts_mut, NonNull};
// MCFG表中的Segement配置部分开始位置为44+16*n
#[repr(C, packed)]
pub struct Segement_Configuration_Space {
pub base_address: u64,
pub segement_group_number: SegmentGroupNumber,
pub bus_begin: u8,
pub bus_end: u8,
pub reverse: u32,
}
/// @brief 获取Segement_Configuration_Space的数量并返回对应数量的Segement_Configuration_Space的切片指针
/// @param head acpi_system_description_table_header_t的指针
/// @return NonNull<[Segement_Configuration_Space]>
pub fn mcfg_find_segment(
head: NonNull<acpi_system_description_table_header_t>,
) -> NonNull<[Segement_Configuration_Space]> {
let table_length = unsafe { (*head.as_ptr()).Length };
let number_of_segments = ((table_length - 44) / 16) as u16;
NonNull::new(slice_from_raw_parts_mut(
(head.as_ptr() as usize + 44) as *mut _,
number_of_segments as usize,
))
.unwrap()
}

View File

@ -0,0 +1 @@
pub mod acpi;

View File

@ -1,16 +1,8 @@
use alloc::{
collections::BTreeMap,
sync::Arc
};
use lazy_static::lazy_static;
use core::fmt::Debug;
use super::{driver::Driver, Device, DeviceState, IdTable};
use crate::libs::spinlock::SpinLock;
use super::{
driver::Driver,
DeviceState,
IdTable,
Device
};
use alloc::{collections::BTreeMap, sync::Arc};
use core::fmt::Debug;
use lazy_static::lazy_static;
/// @brief: 总线状态
#[derive(Debug, Copy, Clone)]

View File

@ -3,9 +3,7 @@ use core::{any::Any, fmt::Debug};
/// @brief: Driver error
#[allow(dead_code)]
#[derive(Debug)]
#[derive(PartialEq, Eq)]
#[derive(Clone, Copy)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum DriverError {
ProbeError,
}

View File

@ -19,11 +19,7 @@ pub enum DeviceType {
}
/// @brief: 设备标识符类型
#[derive(Debug)]
#[derive(Clone)]
#[derive(Hash)]
#[derive(PartialOrd, PartialEq)]
#[derive(Ord, Eq)]
#[derive(Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)]
pub struct IdTable(&'static str, u32);
/// @brief: 设备标识符操作方法集
@ -38,8 +34,7 @@ impl IdTable {
}
/// @brief: 设备当前状态
#[derive(Debug)]
#[derive(Clone, Copy)]
#[derive(Debug, Clone, Copy)]
pub enum DeviceState {
NotInitialized = 0,
Initialized = 1,

View File

@ -1,2 +1,2 @@
pub mod platform;
pub mod device;
pub mod platform;

View File

@ -1,23 +1,16 @@
use alloc::{
collections::{BTreeSet, BTreeMap},
vec::Vec, sync::Arc
};
use lazy_static::lazy_static;
use core::fmt::Debug;
use super::device::{
bus::{
BusDriver,
BusState,
BUS_MANAGER,
Bus
},
bus::{Bus, BusDriver, BusState, BUS_MANAGER},
driver::Driver,
IdTable,
DeviceError,
DeviceState,
DeviceType, Device
Device, DeviceError, DeviceState, DeviceType, IdTable,
};
use crate::libs::{rwlock::RwLock, mutex::Mutex};
use crate::libs::{mutex::Mutex, rwlock::RwLock};
use alloc::{
collections::{BTreeMap, BTreeSet},
sync::Arc,
vec::Vec,
};
use core::fmt::Debug;
use lazy_static::lazy_static;
use platform_device::PlatformDevice;
use platform_driver::PlatformDriver;
@ -57,7 +50,7 @@ impl CompatibleTable {
/// @brief: platform总线驱动
#[derive(Debug)]
pub struct PlatformBusDriver {
pub struct PlatformBusDriver {
drivers: RwLock<BTreeMap<IdTable, Arc<dyn PlatformDriver>>>, // 总线上所有驱动
devices: RwLock<BTreeMap<IdTable, Arc<dyn PlatformDevice>>>, // 总线上所有设备
}
@ -108,7 +101,10 @@ impl PlatformBusDriver {
/// @parameter driver: platform类型驱动该驱动需要实现PlatformDriver trait
/// @return: 注册成功返回Ok(()),注册失败返回BusError类型
#[allow(dead_code)]
fn register_platform_driver(&mut self, driver: Arc<dyn PlatformDriver>) -> Result<(), DeviceError> {
fn register_platform_driver(
&mut self,
driver: Arc<dyn PlatformDriver>,
) -> Result<(), DeviceError> {
let id_table = driver.get_id_table();
let mut drivers = self.drivers.write();
@ -135,7 +131,10 @@ impl PlatformBusDriver {
/// @parameter driver: platform类型设备该驱动需要实现PlatformDevice trait
/// @return: 注册成功返回Ok(()),注册失败返回BusError类型
#[allow(dead_code)]
fn register_platform_device(&mut self, device: Arc<dyn PlatformDevice>) -> Result<(), DeviceError> {
fn register_platform_device(
&mut self,
device: Arc<dyn PlatformDevice>,
) -> Result<(), DeviceError> {
let id_table = device.get_id_table();
let mut devices = self.devices.write();
@ -166,7 +165,10 @@ impl PlatformBusDriver {
let devices = self.devices.read();
for (_dev_id_table, device) in devices.iter() {
if device.get_compatible_table().matches(&driver.get_compatible_table()) {
if device
.get_compatible_table()
.matches(&driver.get_compatible_table())
{
if !device.is_initialized() {
// 设备未初始化调用驱动probe函数
match driver.probe(device.clone()) {
@ -194,7 +196,10 @@ impl PlatformBusDriver {
fn device_match_driver(&self, device: Arc<dyn PlatformDevice>) -> Result<(), DeviceError> {
let drivers = self.drivers.read();
for (_drv_id_table, driver) in &*drivers {
if driver.get_compatible_table().matches(&device.get_compatible_table()) {
if driver
.get_compatible_table()
.matches(&device.get_compatible_table())
{
match driver.probe(device.clone()) {
Ok(_driver) => {
// 将设备状态置为已初始化
@ -228,10 +233,9 @@ impl BusDriver for PlatformBusDriver {
}
/// @brief: platform总线
#[derive(Debug)]
#[derive(Clone)]
#[derive(Debug, Clone)]
pub struct Platform {
state: Arc<Mutex<BusState>>, // 总线状态
state: Arc<Mutex<BusState>>, // 总线状态
driver: Option<Arc<PlatformBusDriver>>, // 总线驱动
}
@ -332,16 +336,26 @@ lazy_static! {
/// @return: None
#[allow(dead_code)]
pub fn platform_bus_init() {
BUS_MANAGER.add_bus_driver(BUS_PLATFORM_DRIVER.get_id_table(), BUS_PLATFORM_DRIVER.clone());
BUS_MANAGER.add_bus(BUS_PLATFORM_DEVICE.get_id_table(), BUS_PLATFORM_DEVICE.clone());
BUS_MANAGER.add_bus_driver(
BUS_PLATFORM_DRIVER.get_id_table(),
BUS_PLATFORM_DRIVER.clone(),
);
BUS_MANAGER.add_bus(
BUS_PLATFORM_DEVICE.get_id_table(),
BUS_PLATFORM_DEVICE.clone(),
);
BUS_PLATFORM_DEVICE.set_state(BusState::Initialized);
}
#[no_mangle]
extern "C" fn c_platform_bus_init() {
BUS_MANAGER.add_bus_driver(BUS_PLATFORM_DRIVER.get_id_table(), BUS_PLATFORM_DRIVER.clone());
BUS_MANAGER.add_bus(BUS_PLATFORM_DEVICE.get_id_table(), BUS_PLATFORM_DEVICE.clone());
BUS_MANAGER.add_bus_driver(
BUS_PLATFORM_DRIVER.get_id_table(),
BUS_PLATFORM_DRIVER.clone(),
);
BUS_MANAGER.add_bus(
BUS_PLATFORM_DEVICE.get_id_table(),
BUS_PLATFORM_DEVICE.clone(),
);
BUS_PLATFORM_DEVICE.set_state(BusState::Initialized);
}

View File

@ -1,12 +1,9 @@
use alloc::sync::Arc;
use super::{
super::device::{
Device,
DeviceType,
DeviceState
},
CompatibleTable, platform_driver::PlatformDriver
super::device::{Device, DeviceState, DeviceType},
platform_driver::PlatformDriver,
CompatibleTable,
};
use alloc::sync::Arc;
/// @brief: 实现该trait的设备实例应挂载在platform总线上
/// 同时应该实现Device trait
@ -35,4 +32,3 @@ pub trait PlatformDevice: Device {
/// @return: None
fn set_driver(&self, driver: Option<Arc<dyn PlatformDriver>>);
}

View File

@ -1,12 +1,9 @@
use alloc::sync::Arc;
use super::{
super::device::driver::{
Driver,
DriverError
},
super::device::driver::{Driver, DriverError},
platform_device::PlatformDevice,
CompatibleTable,
};
use alloc::sync::Arc;
/// @brief: 实现该trait的设备驱动实例应挂载在platform总线上
/// 同时应该实现Driver trait

View File

@ -6,10 +6,7 @@ use crate::filesystem::vfs::{
};
use crate::io::device::BlockDevice;
use crate::syscall::SystemError;
use crate::{
libs::spinlock::SpinLock,
time::TimeSpec,
};
use crate::{libs::spinlock::SpinLock, time::TimeSpec};
use alloc::{
string::String,
sync::{Arc, Weak},

View File

@ -177,7 +177,6 @@ pub fn get_disks_by_name(name: String) -> Result<Arc<LockedAhciDisk>, SystemErro
}
compiler_fence(core::sync::atomic::Ordering::SeqCst);
return Err(SystemError::ENXIO);
}
/// @brief: 通过 ctrl_num 和 port_num 获取 port

View File

@ -1,3 +1,5 @@
pub mod acpi;
pub mod base;
pub mod disk;
pub mod keyboard;
pub mod pci;
@ -6,4 +8,3 @@ pub mod tty;
pub mod uart;
pub mod video;
pub mod virtio;
pub mod base;

View File

@ -14,7 +14,7 @@ struct List *pci_device_structure_list = NULL;
*
*/
void pci_init();
void rs_pci_init();
// pci设备结构的通用标题字段
struct pci_device_structure_header_t
{

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
use crate::{
arch::interrupt::{cli, sti},
include::bindings::bindings::{io_in8, io_out8}, syscall::SystemError,
include::bindings::bindings::{io_in8, io_out8},
syscall::SystemError,
};
pub struct RtcTime {

View File

@ -1,20 +1,23 @@
use core::{ptr::null_mut, sync::atomic::{AtomicBool, Ordering}};
use core::{
ptr::null_mut,
sync::atomic::{AtomicBool, Ordering},
};
use alloc::sync::Arc;
use crate::{
exception::softirq::{SoftirqNumber, SoftirqVec, softirq_vectors},
exception::softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
include::bindings::bindings::video_refresh_framebuffer,
};
#[derive(Debug)]
pub struct VideoRefreshFramebuffer{
running: AtomicBool
pub struct VideoRefreshFramebuffer {
running: AtomicBool,
}
impl SoftirqVec for VideoRefreshFramebuffer {
fn run(&self) {
if self.set_run() == false{
if self.set_run() == false {
return;
}
@ -28,7 +31,7 @@ impl SoftirqVec for VideoRefreshFramebuffer {
impl VideoRefreshFramebuffer {
pub fn new() -> VideoRefreshFramebuffer {
VideoRefreshFramebuffer {
running: AtomicBool::new(false)
running: AtomicBool::new(false),
}
}

View File

@ -1,7 +0,0 @@
all: virtio.o
CFLAGS += -I .
virtio.o: virtio.c
$(CC) $(CFLAGS) -c virtio.c -o virtio.o

View File

@ -1,9 +1,9 @@
//! PCI transport for VirtIO.
use crate::arch::{PciArch, TraitPciArch};
use crate::driver::pci::pci::{
capabilities_offset, pci_bar_init, pci_enable_master, CapabilityIterator, DeviceFunction,
PciDeviceBar, PciError, PCI_CAP_ID_VNDR,
BusDeviceFunction, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
PciStandardDeviceBar, PCI_CAP_ID_VNDR,
};
use crate::include::bindings::bindings::pci_read_config;
use crate::libs::volatile::{
volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
@ -77,7 +77,7 @@ fn device_type(pci_device_id: u16) -> DeviceType {
pub struct PciTransport {
device_type: DeviceType,
/// The bus, device and function identifier for the VirtIO device.
device_function: DeviceFunction,
bus_device_function: BusDeviceFunction,
/// The common configuration structure within some BAR.
common_cfg: NonNull<CommonCfg>,
/// The start of the queue notification region within some BAR.
@ -93,38 +93,26 @@ impl PciTransport {
/// Construct a new PCI VirtIO device driver for the given device function on the given PCI
/// root controller.
///
/// The PCI device must already have had its BARs allocated.
pub fn new<H: Hal>(device_function: DeviceFunction) -> Result<Self, VirtioPciError> {
let device_vendor = unsafe {
let bar_temp = pci_read_config(
device_function.bus,
device_function.device,
device_function.function,
0,
);
bar_temp
};
let device_id = (device_vendor >> 16) as u16;
let vendor_id = device_vendor as u16;
if vendor_id != VIRTIO_VENDOR_ID {
return Err(VirtioPciError::InvalidVendorId(vendor_id));
///
pub fn new<H: Hal>(
device: &mut PciDeviceStructureGeneralDevice,
) -> Result<Self, VirtioPciError> {
let header = &device.common_header;
let bus_device_function = header.bus_device_function;
if header.vendor_id != VIRTIO_VENDOR_ID {
return Err(VirtioPciError::InvalidVendorId(header.vendor_id));
}
let device_type = device_type(device_id);
let device_type = device_type(header.device_id);
// Find the PCI capabilities we need.
let mut common_cfg = None;
let mut notify_cfg = None;
let mut notify_off_multiplier = 0;
let mut isr_cfg = None;
let mut device_cfg = None;
device.bar_init().unwrap()?;
device.enable_master();
//device_capability为迭代器遍历其相当于遍历所有的cap空间
let device_capability = CapabilityIterator {
device_function: device_function,
next_capability_offset: capabilities_offset(device_function),
};
let device_bar = pci_bar_init(device_function)?;
pci_enable_master(device_function);
for capability in device_capability {
for capability in device.capabilities().unwrap() {
if capability.id != PCI_CAP_ID_VNDR {
continue;
}
@ -134,33 +122,16 @@ impl PciTransport {
continue;
}
let struct_info = VirtioCapabilityInfo {
bar: unsafe {
let temp = pci_read_config(
device_function.bus,
device_function.device,
device_function.function,
capability.offset + CAP_BAR_OFFSET,
);
temp as u8
},
offset: unsafe {
let temp = pci_read_config(
device_function.bus,
device_function.device,
device_function.function,
capability.offset + CAP_BAR_OFFSET_OFFSET,
);
temp
},
length: unsafe {
let temp = pci_read_config(
device_function.bus,
device_function.device,
device_function.function,
capability.offset + CAP_LENGTH_OFFSET,
);
temp
},
bar: PciArch::read_config(&bus_device_function, capability.offset + CAP_BAR_OFFSET)
as u8,
offset: PciArch::read_config(
&bus_device_function,
capability.offset + CAP_BAR_OFFSET_OFFSET,
),
length: PciArch::read_config(
&bus_device_function,
capability.offset + CAP_LENGTH_OFFSET,
),
};
match cfg_type {
@ -169,15 +140,10 @@ impl PciTransport {
}
VIRTIO_PCI_CAP_NOTIFY_CFG if cap_len >= 20 && notify_cfg.is_none() => {
notify_cfg = Some(struct_info);
notify_off_multiplier = unsafe {
let temp = pci_read_config(
device_function.bus,
device_function.device,
device_function.function,
capability.offset + CAP_NOTIFY_OFF_MULTIPLIER_OFFSET,
);
temp
};
notify_off_multiplier = PciArch::read_config(
&bus_device_function,
capability.offset + CAP_NOTIFY_OFF_MULTIPLIER_OFFSET,
);
}
VIRTIO_PCI_CAP_ISR_CFG if isr_cfg.is_none() => {
isr_cfg = Some(struct_info);
@ -190,7 +156,7 @@ impl PciTransport {
}
let common_cfg = get_bar_region::<_>(
&device_bar,
&device.standard_device_bar,
&common_cfg.ok_or(VirtioPciError::MissingCommonConfig)?,
)?;
@ -201,19 +167,22 @@ impl PciTransport {
));
}
//kdebug!("notify.offset={},notify.length={}",notify_cfg.offset,notify_cfg.length);
let notify_region = get_bar_region_slice::<_>(&device_bar, &notify_cfg)?;
let notify_region = get_bar_region_slice::<_>(&device.standard_device_bar, &notify_cfg)?;
let isr_status = get_bar_region::<_>(
&device_bar,
&device.standard_device_bar,
&isr_cfg.ok_or(VirtioPciError::MissingIsrConfig)?,
)?;
let config_space = if let Some(device_cfg) = device_cfg {
Some(get_bar_region_slice::<_>(&device_bar, &device_cfg)?)
Some(get_bar_region_slice::<_>(
&device.standard_device_bar,
&device_cfg,
)?)
} else {
None
};
Ok(Self {
device_type,
device_function,
bus_device_function,
common_cfg,
notify_region,
notify_off_multiplier,
@ -487,7 +456,7 @@ impl From<PciError> for VirtioPciError {
///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息
///@return Result<NonNull<T>, VirtioPciError> 成功则返回对应类型的指针失败则返回Error
fn get_bar_region<T>(
device_bar: &PciDeviceBar,
device_bar: &PciStandardDeviceBar,
struct_info: &VirtioCapabilityInfo,
) -> Result<NonNull<T>, VirtioPciError> {
let bar_info = device_bar.get_bar(struct_info.bar)?;
@ -521,7 +490,7 @@ fn get_bar_region<T>(
///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息切片的指针
///@return Result<NonNull<[T]>, VirtioPciError> 成功则返回对应类型的指针切片失败则返回Error
fn get_bar_region_slice<T>(
device_bar: &PciDeviceBar,
device_bar: &PciStandardDeviceBar,
struct_info: &VirtioCapabilityInfo,
) -> Result<NonNull<[T]>, VirtioPciError> {
let ptr = get_bar_region::<T>(device_bar, struct_info)?;

View File

@ -1,46 +0,0 @@
#include "virtio.h"
#include <common/kprint.h>
#include <common/errno.h>
#include <driver/pci/pci.h>
#define MAX_NET_NUM 8 // pci总线上的net设备的最大数量
// 在pci总线上寻找到net设备控制器的header
static struct pci_device_structure_header_t *net_pdevs[MAX_NET_NUM];
static int net_pdevs_count = 0;
static struct pci_device_structure_header_t *virtio_net_pdev;
static int virtio_net_pdev_count = 0;
static uint8_t NETWORK_CLASS = 0x2;
static uint8_t ETHERNET_SUBCLASS = 0x0;
/**
* @brief virtio-net MMIO映射的虚拟地址
* @param virt_addr
* @return 0,
*/
uint8_t get_virtio_net_device(uint8_t * bus, uint8_t *device,uint8_t * function)
{
// 获取所有net-pci设备的列表
pci_get_device_structure(NETWORK_CLASS, ETHERNET_SUBCLASS, net_pdevs, &net_pdevs_count);
//检测其中的virt-io-net设备
for(int i = 0; i < net_pdevs_count;i++) {
struct pci_device_structure_general_device_t *dev = net_pdevs[i];
if(net_pdevs[i]->Vendor_ID==0x1AF4 && net_pdevs[i]->Device_ID>=0x1000 && net_pdevs[i]->Device_ID<=0x103F && dev->Subsystem_ID==1)
{
virtio_net_pdev=net_pdevs[i];
virtio_net_pdev_count++;
break;
}
}
if (virtio_net_pdev_count == 0) {
kwarn("There is no virtio-net device in this computer!");
return NOT_FOUND_DEVICE;
}
if (virtio_net_pdev->Command==0) {
kwarn("The virtio-net device isn't support mmio!");
return NOT_SUPPORTE_MMIO;
}
*bus=virtio_net_pdev->bus;
*device=virtio_net_pdev->device;
*function=virtio_net_pdev->func;
}

View File

@ -1,12 +1,5 @@
#pragma once
#include <common/glib.h>
#define GET_VIRTADDRESS_SUCCESS 0
#define NOT_FOUND_DEVICE 1
#define NOT_SUPPORTE_MMIO 2
#define GET_VIRTADDRESS_FAILURE 3
// 获取virtio-net 设备
uint8_t get_virtio_net_device(uint8_t * bus, uint8_t *device,uint8_t * function);
//寻找并加载所有virtio设备的驱动目前只有virtio-net但其他virtio设备后续也可添加
void c_virtio_probe();

View File

@ -1,53 +1,42 @@
use super::transport_pci::PciTransport;
use super::virtio_impl::HalImpl;
use crate::driver::pci::pci::DeviceFunction;
use crate::include::bindings::bindings::get_virtio_net_device;
use crate::driver::pci::pci::PciDeviceStructureGeneralDevice;
use crate::driver::pci::pci::{
get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
};
use crate::libs::rwlock::RwLockWriteGuard;
use crate::{kdebug, kerror, kwarn};
use alloc::{boxed::Box, collections::LinkedList};
use virtio_drivers::device::net::VirtIONet;
use virtio_drivers::transport::{DeviceType, Transport};
const NETWORK_CLASS: u8 = 0x2;
const ETHERNET_SUBCLASS: u8 = 0x0;
//Virtio设备寻找过程中出现的问题
enum VirtioError {
VirtioNetNotFound,
NetDeviceNotFound,
}
///@brief 寻找并加载所有virtio设备的驱动目前只有virtio-net但其他virtio设备也可添加for c
#[no_mangle]
pub extern "C" fn c_virtio_probe() {
if let Ok(virtio_list) = virtio_device_search() {
for device_function in virtio_list {
match PciTransport::new::<HalImpl>(*device_function) {
Ok(mut transport) => {
kdebug!(
"Detected virtio PCI device with device type {:?}, features {:#018x}",
transport.device_type(),
transport.read_device_features(),
);
virtio_device(transport);
}
Err(err) => {
kerror!("Pci transport create failed because of error: {}", err);
}
}
}
} else {
kerror!("Error occured when finding virtio device!");
}
virtio_probe();
}
///@brief 寻找并加载所有virtio设备的驱动目前只有virtio-net但其他virtio设备也可添加
fn virtio_probe() {
if let Ok(virtio_list) = virtio_device_search() {
for device_function in virtio_list {
match PciTransport::new::<HalImpl>(*device_function) {
pub fn virtio_probe() {
let mut list = PCI_DEVICE_LINKEDLIST.write();
if let Ok(virtio_list) = virtio_device_search(&mut list) {
for virtio_device in virtio_list {
match PciTransport::new::<HalImpl>(virtio_device) {
Ok(mut transport) => {
kdebug!(
"Detected virtio PCI device with device type {:?}, features {:#018x}",
transport.device_type(),
transport.read_device_features(),
);
virtio_device(transport);
virtio_device_init(transport);
}
Err(err) => {
kerror!("Pci transport create failed because of error: {}", err);
@ -60,7 +49,7 @@ fn virtio_probe() {
}
///@brief 为virtio设备寻找对应的驱动进行初始化
fn virtio_device(transport: impl Transport) {
fn virtio_device_init(transport: impl Transport) {
match transport.device_type() {
DeviceType::Block => {
kwarn!("Not support virtio_block device for now");
@ -131,29 +120,38 @@ fn virtio_net<T: Transport>(transport: T) {
}
/// @brief 寻找所有的virtio设备
/// @return Result<LinkedList<Box<DeviceFunction>>,VirtioError> 成功则返回包含所有virtio设备的链表失败则返回err
/// @param list 链表的写锁
/// @return Result<LinkedList<&'a mut Pci_Device_Structure_General_Device>, VirtioError> 成功则返回包含所有virtio设备结构体的可变引用的链表失败则返回err
/// 该函数主要是为其他virtio设备预留支持
fn virtio_device_search() -> Result<LinkedList<Box<DeviceFunction>>, VirtioError> {
let mut virtio_list: LinkedList<Box<DeviceFunction>> = LinkedList::new();
let (bus, device, function) = unsafe {
let mut bus: u8 = 0;
let mut device: u8 = 0;
let mut function: u8 = 0;
let bus_ptr = &mut bus as *mut u8;
let device_ptr = &mut device as *mut u8;
let function_ptr = &mut function as *mut u8;
get_virtio_net_device(bus_ptr, device_ptr, function_ptr);
(bus, device, function)
};
if bus == 0 && device == 0 && function == 0 {
kdebug!("get_virtio_net_device failed");
return Err(VirtioError::VirtioNetNotFound);
}
let device_function = DeviceFunction {
bus: bus,
device: device,
function: function,
};
virtio_list.push_back(Box::new(device_function));
fn virtio_device_search<'a>(
list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
) -> Result<LinkedList<&'a mut PciDeviceStructureGeneralDevice>, VirtioError> {
let mut virtio_list: LinkedList<&mut PciDeviceStructureGeneralDevice> = LinkedList::new();
let virtio_net_device = get_virtio_net_device(list)?;
virtio_list.push_back(virtio_net_device);
Ok(virtio_list)
}
/// @brief 寻找virtio-net设备
/// @param list 链表的写锁
/// @return Result<&'a mut Pci_Device_Structure_General_Device, VirtioError> 成功则返回virtio设备结构体的可变引用失败则返回err
fn get_virtio_net_device<'a>(
list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
) -> Result<&'a mut PciDeviceStructureGeneralDevice, VirtioError> {
let result = get_pci_device_structure_mut(list, NETWORK_CLASS, ETHERNET_SUBCLASS);
if result.is_empty() {
return Err(VirtioError::NetDeviceNotFound);
}
for device in result {
let standard_device = device.as_standard_device_mut().unwrap();
let header = &standard_device.common_header;
if header.vendor_id == 0x1AF4
&& header.device_id >= 0x1000
&& header.device_id <= 0x103F
&& standard_device.subsystem_id == 1
{
return Ok(standard_device);
}
}
Err(VirtioError::VirtioNetNotFound)
}

View File

@ -3,7 +3,6 @@ use crate::include::bindings::bindings::{
alloc_pages, free_pages, memory_management_struct, Page, PAGE_2M_SHIFT, PAGE_2M_SIZE,
PAGE_OFFSET, PAGE_SHARED, ZONE_NORMAL,
};
use crate::mm::virt_2_phys;
use core::mem::size_of;
use core::ptr::NonNull;

View File

@ -3,11 +3,7 @@ use crate::filesystem::vfs::make_rawdev;
use crate::filesystem::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
};
use crate::{
syscall::SystemError,
libs::spinlock::SpinLock,
time::TimeSpec,
};
use crate::{libs::spinlock::SpinLock, syscall::SystemError, time::TimeSpec};
use alloc::{
string::String,
sync::{Arc, Weak},

View File

@ -3,11 +3,7 @@ use crate::filesystem::vfs::make_rawdev;
use crate::filesystem::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
};
use crate::{
syscall::SystemError,
libs::spinlock::SpinLock,
time::TimeSpec,
};
use crate::{libs::spinlock::SpinLock, syscall::SystemError, time::TimeSpec};
use alloc::{
string::String,
sync::{Arc, Weak},

View File

@ -4,7 +4,8 @@ use alloc::{sync::Arc, vec::Vec};
use crate::{
io::{device::LBA_SIZE, disk_info::Partition, SeekFrom},
kerror,
libs::vec_cursor::VecCursor, syscall::SystemError,
libs::vec_cursor::VecCursor,
syscall::SystemError,
};
use super::fs::{Cluster, FATFileSystem};

View File

@ -79,7 +79,12 @@ impl FATFile {
///
/// @return Ok(usize) 成功读取到的字节数
/// @return Err(SystemError) 读取时出现错误,返回错误码
pub fn read(&self, fs: &Arc<FATFileSystem>, buf: &mut [u8], offset: u64) -> Result<usize, SystemError> {
pub fn read(
&self,
fs: &Arc<FATFileSystem>,
buf: &mut [u8],
offset: u64,
) -> Result<usize, SystemError> {
if offset >= self.size() {
return Ok(0);
}
@ -223,7 +228,12 @@ impl FATFile {
///
/// @return Ok(()) 经过操作后offset后面具有长度至少为len的空闲空间
/// @return Err(SystemError) 处理过程中出现了异常。
fn ensure_len(&mut self, fs: &Arc<FATFileSystem>, offset: u64, len: u64) -> Result<(), SystemError> {
fn ensure_len(
&mut self,
fs: &Arc<FATFileSystem>,
offset: u64,
len: u64,
) -> Result<(), SystemError> {
// 文件内本身就还有空余的空间
if offset + len <= self.size() {
return Ok(());
@ -545,7 +555,6 @@ impl FATDir {
} else {
return Err(err_val);
}
}
match r.unwrap() {
@ -822,7 +831,11 @@ impl FATDir {
///
/// @return Ok(FATDirEntry) 目标目录项
/// @return Err(SystemError) 底层传上来的错误码
pub fn get_dir_entry(&self, fs: Arc<FATFileSystem>, name: &str) -> Result<FATDirEntry, SystemError> {
pub fn get_dir_entry(
&self,
fs: Arc<FATFileSystem>,
name: &str,
) -> Result<FATDirEntry, SystemError> {
if name == "." || name == "/" {
return Ok(FATDirEntry::Dir(self.clone()));
}
@ -1271,7 +1284,11 @@ impl ShortDirEntry {
///
/// @return Ok(())
/// @return Err(SystemError) 错误码
pub fn flush(&self, fs: &Arc<FATFileSystem>, disk_bytes_offset: u64) -> Result<(), SystemError> {
pub fn flush(
&self,
fs: &Arc<FATFileSystem>,
disk_bytes_offset: u64,
) -> Result<(), SystemError> {
// 从磁盘读取数据
let blk_offset = fs.get_in_block_offset(disk_bytes_offset);
let lba = fs.get_lba_from_offset(

View File

@ -20,8 +20,8 @@ use crate::{
spinlock::{SpinLock, SpinLockGuard},
vec_cursor::VecCursor,
},
time::TimeSpec,
syscall::SystemError,
time::TimeSpec,
};
use super::{
@ -1569,7 +1569,8 @@ impl IndexNode for LockedFATInode {
dir.check_existence(name, Some(true), guard.fs.upgrade().unwrap())?;
// 再从磁盘删除
let r: Result<(), SystemError> = dir.remove(guard.fs.upgrade().unwrap().clone(), name, true);
let r: Result<(), SystemError> =
dir.remove(guard.fs.upgrade().unwrap().clone(), name, true);
if r.is_ok() {
return r;
} else {

View File

@ -14,16 +14,16 @@ use crate::{
core::{generate_inode_id, ROOT_INODE},
FileType,
},
include::bindings::bindings::{
pid_t, process_find_pcb_by_pid,
},
include::bindings::bindings::{pid_t, process_find_pcb_by_pid},
kerror,
libs::spinlock::{SpinLock, SpinLockGuard},
time::TimeSpec, syscall::SystemError,
syscall::SystemError,
time::TimeSpec,
};
use super::vfs::{
file::{FilePrivateData, FileMode}, FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
file::{FileMode, FilePrivateData},
FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
};
/// @brief 进程文件类型

View File

@ -10,7 +10,8 @@ use alloc::{
use crate::{
filesystem::vfs::{core::generate_inode_id, FileType},
libs::spinlock::{SpinLock, SpinLockGuard},
time::TimeSpec, syscall::SystemError,
syscall::SystemError,
time::TimeSpec,
};
use super::vfs::{

View File

@ -10,10 +10,7 @@ use ::core::{any::Any, fmt::Debug};
use alloc::{string::String, sync::Arc, vec::Vec};
use crate::{
time::TimeSpec,
syscall::SystemError,
};
use crate::{syscall::SystemError, time::TimeSpec};
use self::{core::generate_inode_id, file::FileMode};
pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
@ -239,7 +236,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
///
/// @return 成功 Ok(())
/// @return 失败 Err(错误码)
fn rmdir(&self, _name: &str) ->Result<(), SystemError>{
fn rmdir(&self, _name: &str) -> Result<(), SystemError> {
return Err(SystemError::ENOTSUP);
}

View File

@ -5,11 +5,9 @@ use alloc::{
sync::{Arc, Weak},
};
use crate::{
libs::spinlock::SpinLock, syscall::SystemError,
};
use crate::{libs::spinlock::SpinLock, syscall::SystemError};
use super::{FilePrivateData, FileSystem, FileType, IndexNode, InodeId, file::FileMode};
use super::{file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode, InodeId};
/// @brief 挂载文件系统
/// 挂载文件系统的时候套了MountFS这一层以实现文件系统的递归挂载
@ -166,9 +164,7 @@ impl IndexNode for MountFSInode {
buf: &[u8],
data: &mut FilePrivateData,
) -> Result<usize, SystemError> {
return self
.inner_inode
.write_at(offset, len, buf, data);
return self.inner_inode.write_at(offset, len, buf, data);
}
#[inline]

View File

@ -1,5 +1,5 @@
/// 引入Module
use crate::{syscall::SystemError};
use crate::syscall::SystemError;
use alloc::{sync::Arc, vec::Vec};
use core::{any::Any, fmt::Debug};
@ -45,7 +45,6 @@ pub trait Device: Any + Send + Sync + Debug {
fn sync(&self) -> Result<(), SystemError>;
// TODO: 待实现 open, close
}
/// @brief 块设备应该实现的操作
@ -58,7 +57,12 @@ pub trait BlockDevice: Any + Send + Sync + Debug {
/// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
/// 否则返回Err(错误码),其中错误码为负数;
/// 如果操作异常但是并没有检查出什么错误将返回Err(已操作的长度)
fn read_at(&self, lba_id_start: BlockId, count: usize, buf: &mut [u8]) -> Result<usize, SystemError>;
fn read_at(
&self,
lba_id_start: BlockId,
count: usize,
buf: &mut [u8],
) -> Result<usize, SystemError>;
/// @brief: 在块设备中从第lba_id_start个块开始把buf中的count个块数据存放到设备中
/// @parameter lba_id_start: 起始块
@ -67,7 +71,12 @@ pub trait BlockDevice: Any + Send + Sync + Debug {
/// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
/// 否则返回Err(错误码),其中错误码为负数;
/// 如果操作异常但是并没有检查出什么错误将返回Err(已操作的长度)
fn write_at(&self, lba_id_start: BlockId, count: usize, buf: &[u8]) -> Result<usize, SystemError>;
fn write_at(
&self,
lba_id_start: BlockId,
count: usize,
buf: &[u8],
) -> Result<usize, SystemError>;
/// @brief: 同步磁盘信息把所有的dirty数据写回硬盘 - 待实现
fn sync(&self) -> Result<(), SystemError>;

View File

@ -13,9 +13,8 @@ use crate::{
},
include::bindings::bindings::{
pid_t, process_control_block, process_do_exit, process_find_pcb_by_pid, pt_regs,
spinlock_t, verify_area, NULL, PF_EXITING,
PF_KTHREAD, PF_SIGNALED, PF_WAKEKILL, PROC_INTERRUPTIBLE, USER_CS, USER_DS,
USER_MAX_LINEAR_ADDR,
spinlock_t, verify_area, NULL, PF_EXITING, PF_KTHREAD, PF_SIGNALED, PF_WAKEKILL,
PROC_INTERRUPTIBLE, USER_CS, USER_DS, USER_MAX_LINEAR_ADDR,
},
ipc::signal_types::{sigset_add, user_sigaction},
kBUG, kdebug, kerror, kwarn,
@ -29,7 +28,8 @@ use crate::{
process::{
pid::PidType,
process::{process_is_stopped, process_kick, process_wake_up_state},
}, syscall::SystemError,
},
syscall::SystemError,
};
use super::signal_types::{
@ -698,7 +698,7 @@ fn setup_frame(
if err != 0 {
// todo: 在这里生成一个sigsegv,然后core dump
//临时解决方案:退出当前进程
unsafe{
unsafe {
process_do_exit(1);
}
}
@ -725,7 +725,11 @@ fn setup_frame(
regs.cs = (USER_CS | 0x3) as u64;
regs.ds = (USER_DS | 0x3) as u64;
return if err == 0 { Ok(0) } else { Err(SystemError::EPERM) };
return if err == 0 {
Ok(0)
} else {
Err(SystemError::EPERM)
};
}
#[inline(always)]
@ -762,7 +766,11 @@ fn copy_siginfo_to_user(to: *mut siginfo, from: &siginfo) -> Result<i32, SystemE
/// @param context 要被设置的目标sigcontext
/// @param mask 要被暂存的信号mask标志位
/// @param regs 进入信号处理流程前Restore all要弹出的内核栈栈帧
fn setup_sigcontext(context: &mut sigcontext, mask: &sigset_t, regs: &pt_regs) -> Result<i32, SystemError> {
fn setup_sigcontext(
context: &mut sigcontext,
mask: &sigset_t,
regs: &pt_regs,
) -> Result<i32, SystemError> {
let current_thread = current_pcb().thread;
context.oldmask = *mask;
@ -929,19 +937,18 @@ pub extern "C" fn sys_sigaction(regs: &mut pt_regs) -> u64 {
}
}
//return retval as u64;
if retval.is_ok(){
if retval.is_ok() {
return 0;
}else{
} else {
return retval.unwrap_err().to_posix_errno() as u64;
}
}
fn do_sigaction(
sig: SignalNumber,
act: Option<&mut sigaction>,
old_act: Option<&mut sigaction>,
) -> Result<(),SystemError> {
) -> Result<(), SystemError> {
let pcb = current_pcb();
// 指向当前信号的action的引用

View File

@ -665,5 +665,5 @@ pub struct signal_stack {
pub sp: *mut c_void,
pub flags: u32,
pub size: u32,
pub fpstate:FpState,
pub fpstate: FpState,
}

View File

@ -12,8 +12,6 @@
use core::panic::PanicInfo;
/// 导出x86_64架构相关的代码命名为arch模块
#[cfg(target_arch = "x86_64")]
#[path = "arch/x86_64/mod.rs"]
#[macro_use]
mod arch;
#[macro_use]

View File

@ -1,9 +1,6 @@
#![allow(dead_code)]
use super::spinlock::RawSpinlock;
use crate::{
arch::asm::cmpxchg::try_cmpxchg_q,
syscall::SystemError,
};
use crate::{arch::asm::cmpxchg::try_cmpxchg_q, syscall::SystemError};
use core::{fmt::Debug, intrinsics::size_of};
#[cfg(target_arch = "x86_64")]
@ -53,7 +50,7 @@ impl LockRef {
fn cmpxchg_loop(&mut self, mode: CmpxchgMode) -> Result<i32, i32> {
use core::ptr::read_volatile;
use crate::{arch::cpu::cpu_relax};
use crate::arch::cpu::cpu_relax;
let mut old: LockRef = LockRef::INIT;
old.count = unsafe { read_volatile(&self.count) };
@ -265,7 +262,7 @@ impl LockRef {
let cmpxchg_result = self.cmpxchg_loop(CmpxchgMode::DecreaseNotZero);
if cmpxchg_result.is_ok() {
return Ok(cmpxchg_result.unwrap());
} else if cmpxchg_result.unwrap_err() == 1{
} else if cmpxchg_result.unwrap_err() == 1 {
return Err(SystemError::EPERM);
}
}

View File

@ -8,9 +8,10 @@ use alloc::collections::LinkedList;
use crate::{
arch::{asm::current::current_pcb, sched::sched},
include::bindings::bindings::{
pid_t, process_control_block, process_wakeup, PROC_INTERRUPTIBLE, PROC_RUNNING,
pid_t, process_control_block, process_wakeup, PROC_INTERRUPTIBLE, PROC_RUNNING,
},
libs::spinlock::SpinLockGuard, syscall::SystemError,
libs::spinlock::SpinLockGuard,
syscall::SystemError,
};
use super::spinlock::SpinLock;

View File

@ -12,13 +12,13 @@
#![allow(dead_code)]
use core::cmp::Ord;
use core::fmt::{self, Debug};
use core::cmp::Ordering;
use core::ptr;
use core::iter::{IntoIterator, FromIterator};
use core::fmt::{self, Debug};
use core::iter::{FromIterator, IntoIterator};
use core::marker;
use core::mem;
use core::ops::Index;
use core::ptr;
use alloc::boxed::Box;
@ -234,7 +234,6 @@ impl<K: Ord, V> NodePtr<K, V> {
unsafe { (*self.0).right = right }
}
#[inline]
fn parent(&self) -> NodePtr<K, V> {
if self.is_null() {
@ -421,9 +420,8 @@ where
return false;
}
self.iter().all(|(key, value)| {
other.get(key).map_or(false, |v| *value == *v)
})
self.iter()
.all(|(key, value)| other.get(key).map_or(false, |v| *value == *v))
}
}
@ -446,7 +444,6 @@ where
}
}
impl<K: Ord, V> FromIterator<(K, V)> for RBTree<K, V> {
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> RBTree<K, V> {
let mut tree = RBTree::new();
@ -483,7 +480,9 @@ pub struct Keys<'a, K: Ord + 'a, V: 'a> {
impl<'a, K: Ord, V> Clone for Keys<'a, K, V> {
fn clone(&self) -> Keys<'a, K, V> {
Keys { inner: self.inner.clone() }
Keys {
inner: self.inner.clone(),
}
}
}
@ -526,7 +525,9 @@ pub struct Values<'a, K: 'a + Ord, V: 'a> {
impl<'a, K: Ord, V> Clone for Values<'a, K, V> {
fn clone(&self) -> Values<'a, K, V> {
Values { inner: self.inner.clone() }
Values {
inner: self.inner.clone(),
}
}
}
@ -536,7 +537,6 @@ impl<'a, K: Ord + Debug, V: Debug> fmt::Debug for Values<'a, K, V> {
}
}
impl<'a, K: Ord, V> Iterator for Values<'a, K, V> {
type Item = &'a V;
@ -573,7 +573,9 @@ pub struct ValuesMut<'a, K: 'a + Ord, V: 'a> {
impl<'a, K: Ord, V> Clone for ValuesMut<'a, K, V> {
fn clone(&self) -> ValuesMut<'a, K, V> {
ValuesMut { inner: self.inner.clone() }
ValuesMut {
inner: self.inner.clone(),
}
}
}
@ -812,7 +814,6 @@ impl<'a, K: Ord + 'a, V: 'a> DoubleEndedIterator for IterMut<'a, K, V> {
}
}
impl<K: Ord, V> IntoIterator for RBTree<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
@ -1387,7 +1388,9 @@ impl<K: Ord, V> RBTree<K, V> {
/// Return the value iter mut
#[inline]
pub fn values_mut(&mut self) -> ValuesMut<K, V> {
ValuesMut { inner: self.iter_mut() }
ValuesMut {
inner: self.iter_mut(),
}
}
/// Return the key and value iter
@ -1441,7 +1444,6 @@ mod tests {
assert_eq!(*m.get(&2).unwrap(), 6);
}
#[test]
fn test_clone() {
let mut m = RBTree::new();

View File

@ -7,7 +7,7 @@ use core::{
sync::atomic::{AtomicU32, Ordering},
};
use crate::{syscall::SystemError};
use crate::syscall::SystemError;
///RwLock读写锁

View File

@ -147,6 +147,7 @@ void system_initialize()
// ps2_mouse_init();
// ata_init();
pci_init();
rs_pci_init();
io_mfence();
// test_slab();

View File

@ -4,8 +4,8 @@ use crate::{
arch::asm::current::current_pcb,
include::bindings::bindings::{
initial_mm, mm_create_vma, mm_unmap, vm_area_del, vm_area_free, vm_area_struct, vm_flags_t,
vma_find, MMIO_BASE, MMIO_TOP, PAGE_1G_SHIFT, PAGE_1G_SIZE,
PAGE_2M_SIZE, PAGE_4K_SHIFT, PAGE_4K_SIZE, VM_DONTCOPY, VM_IO,
vma_find, MMIO_BASE, MMIO_TOP, PAGE_1G_SHIFT, PAGE_1G_SIZE, PAGE_2M_SIZE, PAGE_4K_SHIFT,
PAGE_4K_SIZE, VM_DONTCOPY, VM_IO,
},
kdebug, kerror,
};

View File

@ -1,4 +1,4 @@
use crate::include::bindings::bindings::{PAGE_OFFSET, process_control_block, mm_struct};
use crate::include::bindings::bindings::{mm_struct, process_control_block, PAGE_OFFSET};
pub mod allocator;
pub mod gfp;

View File

@ -16,7 +16,8 @@ use crate::{
ffi_convert::FFIBind2Rust,
refcount::{refcount_inc, RefCount},
spinlock::{spin_lock_irqsave, spin_unlock_irqrestore},
}, syscall::SystemError,
},
syscall::SystemError,
};
#[no_mangle]

View File

@ -1,3 +1,4 @@
use num_traits::{FromPrimitive, ToPrimitive};
#[repr(i32)]