From 78bf93f02f84bf5e024ddfb559f040e68ce39ccf Mon Sep 17 00:00:00 2001 From: YJwu2023 Date: Sun, 9 Apr 2023 12:30:02 +0800 Subject: [PATCH] =?UTF-8?q?pci=E9=87=8D=E6=9E=84+pcie=E6=94=AF=E6=8C=81=20?= =?UTF-8?q?(#235)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * pci重构+pcie支持 * pci重构测试完成 * 修正makefile的问题 * 小修改 * 修改函数名字 --- kernel/src/arch/mod.rs | 27 + kernel/src/arch/x86_64/context.rs | 2 +- kernel/src/arch/x86_64/mod.rs | 3 +- kernel/src/arch/x86_64/pci/mod.rs | 1 + kernel/src/arch/x86_64/pci/pci.rs | 70 + kernel/src/arch/x86_64/x86_64_pci.c | 0 kernel/src/arch/x86_64/x86_64_pci.h | 0 kernel/src/driver/Makefile | 2 +- kernel/src/driver/acpi/acpi.c | 16 + kernel/src/driver/acpi/acpi.h | 9 + kernel/src/driver/acpi/acpi.rs | 27 + kernel/src/driver/acpi/mod.rs | 1 + kernel/src/driver/base/device/bus.rs | 16 +- kernel/src/driver/base/device/driver.rs | 4 +- kernel/src/driver/base/device/mod.rs | 9 +- kernel/src/driver/base/mod.rs | 2 +- kernel/src/driver/base/platform/mod.rs | 88 +- .../driver/base/platform/platform_device.rs | 12 +- .../driver/base/platform/platform_driver.rs | 7 +- kernel/src/driver/disk/ahci/ahci_inode.rs | 5 +- kernel/src/driver/disk/ahci/mod.rs | 1 - kernel/src/driver/keyboard/mod.rs | 2 +- kernel/src/driver/mod.rs | 3 +- kernel/src/driver/pci/pci.h | 2 +- kernel/src/driver/pci/pci.rs | 1184 +++++++++++++++-- kernel/src/driver/timers/rtc/rtc.rs | 3 +- kernel/src/driver/video/mod.rs | 17 +- kernel/src/driver/virtio/Makefile | 7 - kernel/src/driver/virtio/transport_pci.rs | 111 +- kernel/src/driver/virtio/virtio.c | 46 - kernel/src/driver/virtio/virtio.h | 7 - kernel/src/driver/virtio/virtio.rs | 98 +- kernel/src/driver/virtio/virtio_impl.rs | 1 - kernel/src/filesystem/devfs/null_dev.rs | 6 +- kernel/src/filesystem/devfs/zero_dev.rs | 6 +- kernel/src/filesystem/fat/bpb.rs | 3 +- kernel/src/filesystem/fat/entry.rs | 27 +- kernel/src/filesystem/fat/fs.rs | 5 +- kernel/src/filesystem/procfs/mod.rs | 10 +- kernel/src/filesystem/ramfs/mod.rs | 3 +- kernel/src/filesystem/vfs/mod.rs | 7 +- kernel/src/filesystem/vfs/mount.rs | 10 +- kernel/src/io/device.rs | 17 +- kernel/src/ipc/signal.rs | 31 +- kernel/src/ipc/signal_types.rs | 2 +- kernel/src/lib.rs | 2 - kernel/src/libs/lockref.rs | 9 +- kernel/src/libs/mutex.rs | 5 +- kernel/src/libs/rbtree.rs | 34 +- kernel/src/libs/rwlock.rs | 2 +- kernel/src/libs/volatile.rs | 4 +- kernel/src/main.c | 1 + kernel/src/mm/mmio_buddy.rs | 4 +- kernel/src/mm/mod.rs | 4 +- kernel/src/process/fork.rs | 3 +- kernel/src/syscall/mod.rs | 1 + 56 files changed, 1478 insertions(+), 501 deletions(-) create mode 100644 kernel/src/arch/mod.rs create mode 100644 kernel/src/arch/x86_64/pci/mod.rs create mode 100644 kernel/src/arch/x86_64/pci/pci.rs delete mode 100644 kernel/src/arch/x86_64/x86_64_pci.c delete mode 100644 kernel/src/arch/x86_64/x86_64_pci.h create mode 100644 kernel/src/driver/acpi/acpi.rs create mode 100644 kernel/src/driver/acpi/mod.rs delete mode 100644 kernel/src/driver/virtio/Makefile delete mode 100644 kernel/src/driver/virtio/virtio.c diff --git a/kernel/src/arch/mod.rs b/kernel/src/arch/mod.rs new file mode 100644 index 00000000..2e9a074b --- /dev/null +++ b/kernel/src/arch/mod.rs @@ -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 转换结果或出错原因 + fn address_pci_to_address_memory(address: usize) -> Result; + /// @brief 获取Segement的root地址,x86_64架构为acpi mcfg表中读取 + /// @param segement 组id + /// @return Result 转换结果或出错原因 + fn ecam_root(segement: SegmentGroupNumber) -> Result; +} diff --git a/kernel/src/arch/x86_64/context.rs b/kernel/src/arch/x86_64/context.rs index 91750348..2c1a9576 100644 --- a/kernel/src/arch/x86_64/context.rs +++ b/kernel/src/arch/x86_64/context.rs @@ -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 切换进程的上下文(没有切换页表的动作) /// diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index 83450a21..12aafea4 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -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; diff --git a/kernel/src/arch/x86_64/pci/mod.rs b/kernel/src/arch/x86_64/pci/mod.rs new file mode 100644 index 00000000..7652d2c4 --- /dev/null +++ b/kernel/src/arch/x86_64/pci/mod.rs @@ -0,0 +1 @@ +pub mod pci; diff --git a/kernel/src/arch/x86_64/pci/pci.rs b/kernel/src/arch/x86_64/pci/pci.rs new file mode 100644 index 00000000..3c3a4405 --- /dev/null +++ b/kernel/src/arch/x86_64/pci/pci.rs @@ -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 { + Ok(address) + } + + fn ecam_root(segement: SegmentGroupNumber) -> Result { + 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); + } +} diff --git a/kernel/src/arch/x86_64/x86_64_pci.c b/kernel/src/arch/x86_64/x86_64_pci.c deleted file mode 100644 index e69de29b..00000000 diff --git a/kernel/src/arch/x86_64/x86_64_pci.h b/kernel/src/arch/x86_64/x86_64_pci.h deleted file mode 100644 index e69de29b..00000000 diff --git a/kernel/src/driver/Makefile b/kernel/src/driver/Makefile index e16d23a9..df9f5458 100644 --- a/kernel/src/driver/Makefile +++ b/kernel/src/driver/Makefile @@ -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 "$@" diff --git a/kernel/src/driver/acpi/acpi.c b/kernel/src/driver/acpi/acpi.c index 3fc42664..e7f69f77 100644 --- a/kernel/src/driver/acpi/acpi.c +++ b/kernel/src/driver/acpi/acpi.c @@ -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模块 * diff --git a/kernel/src/driver/acpi/acpi.h b/kernel/src/driver/acpi/acpi.h index 0e03a215..e0d99946 100644 --- a/kernel/src/driver/acpi/acpi.h +++ b/kernel/src/driver/acpi/acpi.h @@ -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(); \ No newline at end of file diff --git a/kernel/src/driver/acpi/acpi.rs b/kernel/src/driver/acpi/acpi.rs new file mode 100644 index 00000000..0db6cc04 --- /dev/null +++ b/kernel/src/driver/acpi/acpi.rs @@ -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, +) -> 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() +} diff --git a/kernel/src/driver/acpi/mod.rs b/kernel/src/driver/acpi/mod.rs new file mode 100644 index 00000000..36731ae8 --- /dev/null +++ b/kernel/src/driver/acpi/mod.rs @@ -0,0 +1 @@ +pub mod acpi; diff --git a/kernel/src/driver/base/device/bus.rs b/kernel/src/driver/base/device/bus.rs index f574c13a..9fb697e3 100644 --- a/kernel/src/driver/base/device/bus.rs +++ b/kernel/src/driver/base/device/bus.rs @@ -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)] diff --git a/kernel/src/driver/base/device/driver.rs b/kernel/src/driver/base/device/driver.rs index ef43a7f5..2a319e19 100644 --- a/kernel/src/driver/base/device/driver.rs +++ b/kernel/src/driver/base/device/driver.rs @@ -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, } diff --git a/kernel/src/driver/base/device/mod.rs b/kernel/src/driver/base/device/mod.rs index 0f275d56..cac37bef 100644 --- a/kernel/src/driver/base/device/mod.rs +++ b/kernel/src/driver/base/device/mod.rs @@ -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, diff --git a/kernel/src/driver/base/mod.rs b/kernel/src/driver/base/mod.rs index 47bdb283..9ea87935 100644 --- a/kernel/src/driver/base/mod.rs +++ b/kernel/src/driver/base/mod.rs @@ -1,2 +1,2 @@ +pub mod device; pub mod platform; -pub mod device; \ No newline at end of file diff --git a/kernel/src/driver/base/platform/mod.rs b/kernel/src/driver/base/platform/mod.rs index 4a7e295d..32cfdc87 100644 --- a/kernel/src/driver/base/platform/mod.rs +++ b/kernel/src/driver/base/platform/mod.rs @@ -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 - }, - driver::Driver, - IdTable, - DeviceError, - DeviceState, - DeviceType, Device + bus::{Bus, BusDriver, BusState, BUS_MANAGER}, + driver::Driver, + 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>>, // 总线上所有驱动 devices: RwLock>>, // 总线上所有设备 } @@ -108,14 +101,17 @@ impl PlatformBusDriver { /// @parameter driver: platform类型驱动,该驱动需要实现PlatformDriver trait /// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型 #[allow(dead_code)] - fn register_platform_driver(&mut self, driver: Arc) -> Result<(), DeviceError> { + fn register_platform_driver( + &mut self, + driver: Arc, + ) -> Result<(), DeviceError> { let id_table = driver.get_id_table(); let mut drivers = self.drivers.write(); // 如果存在同类型的驱动,返回错误 if drivers.contains_key(&id_table) { return Err(DeviceError::DriverExists); - } else { + } else { drivers.insert(id_table.clone(), driver.clone()); return Ok(()); } @@ -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) -> Result<(), DeviceError> { + fn register_platform_device( + &mut self, + device: Arc, + ) -> 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,9 +196,12 @@ impl PlatformBusDriver { fn device_match_driver(&self, device: Arc) -> 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) => { + Ok(_driver) => { // 将设备状态置为已初始化 device.set_state(DeviceState::Initialized); return Ok(()); @@ -228,10 +233,9 @@ impl BusDriver for PlatformBusDriver { } /// @brief: platform总线 -#[derive(Debug)] -#[derive(Clone)] -pub struct Platform { - state: Arc>, // 总线状态 +#[derive(Debug, Clone)] +pub struct Platform { + state: Arc>, // 总线状态 driver: Option>, // 总线驱动 } @@ -266,7 +270,7 @@ impl Platform { match *state { BusState::Initialized => true, _ => false, - } + } } /// @brief: 设置总线状态 @@ -288,7 +292,7 @@ impl Platform { return *state; } - /// @brief: + /// @brief: /// @parameter: None /// @return: 总线状态 #[inline] @@ -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); } - - diff --git a/kernel/src/driver/base/platform/platform_device.rs b/kernel/src/driver/base/platform/platform_device.rs index 7c72408f..f02f88ae 100644 --- a/kernel/src/driver/base/platform/platform_device.rs +++ b/kernel/src/driver/base/platform/platform_device.rs @@ -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>); } - diff --git a/kernel/src/driver/base/platform/platform_driver.rs b/kernel/src/driver/base/platform/platform_driver.rs index 95d2e161..e0d305bf 100644 --- a/kernel/src/driver/base/platform/platform_driver.rs +++ b/kernel/src/driver/base/platform/platform_driver.rs @@ -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 diff --git a/kernel/src/driver/disk/ahci/ahci_inode.rs b/kernel/src/driver/disk/ahci/ahci_inode.rs index 208f2380..5f7564a1 100644 --- a/kernel/src/driver/disk/ahci/ahci_inode.rs +++ b/kernel/src/driver/disk/ahci/ahci_inode.rs @@ -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}, diff --git a/kernel/src/driver/disk/ahci/mod.rs b/kernel/src/driver/disk/ahci/mod.rs index 13843d72..d886acd2 100644 --- a/kernel/src/driver/disk/ahci/mod.rs +++ b/kernel/src/driver/disk/ahci/mod.rs @@ -177,7 +177,6 @@ pub fn get_disks_by_name(name: String) -> Result, SystemErro } compiler_fence(core::sync::atomic::Ordering::SeqCst); return Err(SystemError::ENXIO); - } /// @brief: 通过 ctrl_num 和 port_num 获取 port diff --git a/kernel/src/driver/keyboard/mod.rs b/kernel/src/driver/keyboard/mod.rs index d16c8b0f..38b67e6b 100644 --- a/kernel/src/driver/keyboard/mod.rs +++ b/kernel/src/driver/keyboard/mod.rs @@ -1,2 +1,2 @@ pub mod ps2_keyboard; -// pub mod ps2_keyboard_inode; \ No newline at end of file +// pub mod ps2_keyboard_inode; diff --git a/kernel/src/driver/mod.rs b/kernel/src/driver/mod.rs index b91a33f1..4b789242 100644 --- a/kernel/src/driver/mod.rs +++ b/kernel/src/driver/mod.rs @@ -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; diff --git a/kernel/src/driver/pci/pci.h b/kernel/src/driver/pci/pci.h index e4eb961a..92814bd4 100644 --- a/kernel/src/driver/pci/pci.h +++ b/kernel/src/driver/pci/pci.h @@ -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 { diff --git a/kernel/src/driver/pci/pci.rs b/kernel/src/driver/pci/pci.rs index 0f8ffdc1..02c433ee 100644 --- a/kernel/src/driver/pci/pci.rs +++ b/kernel/src/driver/pci/pci.rs @@ -1,19 +1,123 @@ +#![allow(dead_code)] +// 目前仅支持单主桥单Segment + +use crate::arch::{PciArch, TraitPciArch}; use crate::include::bindings::bindings::{ - initial_mm, mm_map, mm_struct, pci_read_config, pci_write_config, VM_DONTCOPY, VM_IO, + initial_mm, mm_map, mm_struct, PAGE_2M_SIZE, VM_DONTCOPY, VM_IO, }; +use crate::libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; use crate::mm::mmio_buddy::MMIO_POOL; -use crate::{kdebug, kerror, kwarn}; +use crate::{kdebug, kerror, kinfo, kwarn}; +use alloc::vec::Vec; +use alloc::{boxed::Box, collections::LinkedList}; use bitflags::bitflags; use core::{ convert::TryFrom, fmt::{self, Display, Formatter}, }; +// PCI_DEVICE_LINKEDLIST 添加了读写锁的全局链表,里面存储了检索到的PCI设备结构体 +// PCI_ROOT_0 Segment为0的全局PciRoot +lazy_static! { + pub static ref PCI_DEVICE_LINKEDLIST: PciDeviceLinkedList = PciDeviceLinkedList::new(); + pub static ref PCI_ROOT_0: Option = { + match PciRoot::new(0) { + Ok(root) => Some(root), + Err(err) => { + kerror!("Pci_root init failed because of error: {}", err); + None + } + } + }; +} + +/// 添加了读写锁的链表,存储PCI设备结构体 +pub struct PciDeviceLinkedList { + list: RwLock>>, +} + +impl PciDeviceLinkedList { + /// @brief 初始化结构体 + fn new() -> Self { + PciDeviceLinkedList { + list: RwLock::new(LinkedList::new()), + } + } + /// @brief 获取可读的linkedlist(读锁守卫) + /// @return RwLockReadGuard>> 读锁守卫 + pub fn read( + &self, + ) -> RwLockReadGuard>> { + self.list.read() + } + /// @brief 获取可写的linkedlist(写锁守卫) + /// @return RwLockWriteGuard>> 写锁守卫 + pub fn write( + &self, + ) -> RwLockWriteGuard>> { + self.list.write() + } + /// @brief 获取链表中PCI结构体数目 + /// @return usize 链表中PCI结构体数目 + pub fn num(&self) -> usize { + let list = self.list.read(); + list.len() + } + /// @brief 添加Pci设备结构体到链表中 + pub fn add(&self, device: Box) { + let mut list = self.list.write(); + list.push_back(device); + } +} + +/// @brief 在链表中寻找满足条件的PCI设备结构体并返回其可变引用 +/// @param list 链表的写锁守卫 +/// @param class_code 寄存器值 +/// @param subclass 寄存器值,与class_code一起确定设备类型 +/// @return Vec<&'a mut Box<(dyn PciDeviceStructure) 包含链表中所有满足条件的PCI结构体的可变引用的容器 +pub fn get_pci_device_structure_mut<'a>( + list: &'a mut RwLockWriteGuard<'_, LinkedList>>, + class_code: u8, + subclass: u8, +) -> Vec<&'a mut Box<(dyn PciDeviceStructure)>> { + let mut result = Vec::new(); + for box_pci_device_structure in list.iter_mut() { + let common_header = (*box_pci_device_structure).common_header(); + if (common_header.class_code == class_code) && (common_header.subclass == subclass) { + result.push(box_pci_device_structure); + } + } + result +} +/// @brief 在链表中寻找满足条件的PCI设备结构体并返回其不可变引用 +/// @param list 链表的读锁守卫 +/// @param class_code 寄存器值 +/// @param subclass 寄存器值,与class_code一起确定设备类型 +/// @return Vec<&'a Box<(dyn PciDeviceStructure) 包含链表中所有满足条件的PCI结构体的不可变引用的容器 +pub fn get_pci_device_structure<'a>( + list: &'a mut RwLockReadGuard<'_, LinkedList>>, + class_code: u8, + subclass: u8, +) -> Vec<&'a Box<(dyn PciDeviceStructure)>> { + let mut result = Vec::new(); + for box_pci_device_structure in list.iter() { + let common_header = (*box_pci_device_structure).common_header(); + if (common_header.class_code == class_code) && (common_header.subclass == subclass) { + result.push(box_pci_device_structure); + } + } + result +} + //Bar0寄存器的offset const BAR0_OFFSET: u8 = 0x10; //Status、Command寄存器的offset const STATUS_COMMAND_OFFSET: u8 = 0x04; /// ID for vendor-specific PCI capabilities.(Virtio Capabilities) pub const PCI_CAP_ID_VNDR: u8 = 0x09; +pub const PORT_PCI_CONFIG_ADDRESS: u16 = 0xcf8; +pub const PORT_PCI_CONFIG_DATA: u16 = 0xcfc; +// pci设备分组的id +pub type SegmentGroupNumber = u16; //理论上最多支持65535个Segment_Group bitflags! { /// The status register in PCI configuration space. @@ -46,7 +150,7 @@ bitflags! { bitflags! { /// The command register in PCI configuration space. - pub struct CommandRegister: u16 { + pub struct Command: u16 { /// The device can respond to I/O Space accesses. const IO_SPACE = 1 << 0; /// The device can respond to Memory Space accesses. @@ -71,39 +175,874 @@ bitflags! { } } -/// Gets the capabilities 'pointer' for the device function, if any. -///@brief 获取第一个capability 的offset -///@param device_function PCI设备的唯一标识 -///@return Option offset -pub fn capabilities_offset(device_function: DeviceFunction) -> Option { - let status: Status = unsafe { - let temp = pci_read_config( - device_function.bus, - device_function.device, - device_function.function, +/// The type of a PCI device function header. +/// 标头类型/设备类型 +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum HeaderType { + /// A normal PCI device. + Standard, + /// A PCI to PCI bridge. + PciPciBridge, + /// A PCI to CardBus bridge. + PciCardbusBridge, + /// Unrecognised header type. + Unrecognised(u8), +} +/// u8到HeaderType的转换 +impl From for HeaderType { + fn from(value: u8) -> Self { + match value { + 0x00 => Self::Standard, + 0x01 => Self::PciPciBridge, + 0x02 => Self::PciCardbusBridge, + _ => Self::Unrecognised(value), + } + } +} +/// Pci可能触发的各种错误 +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum PciError { + /// The device reported an invalid BAR type. + InvalidBarType, + CreateMmioError, + InvalidBusDeviceFunction, + SegmentNotFound, + GetWrongHeader, + UnrecognisedHeaderType, + PciDeviceStructureTransformError, +} +///实现PciError的Display trait,使其可以直接输出 +impl Display for PciError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + Self::InvalidBarType => write!(f, "Invalid PCI BAR type."), + Self::CreateMmioError => write!(f, "Error occurred while creating mmio."), + Self::InvalidBusDeviceFunction => write!(f, "Found invalid BusDeviceFunction."), + Self::SegmentNotFound => write!(f, "Target segment not found"), + Self::GetWrongHeader => write!(f, "GetWrongHeader with vendor id 0xffff"), + Self::UnrecognisedHeaderType => write!(f, "Found device with unrecognised header type"), + Self::PciDeviceStructureTransformError => { + write!(f, "Found None When transform Pci device structure") + } + } + } +} + +/// trait类型Pci_Device_Structure表示pci设备,动态绑定三种具体设备类型:Pci_Device_Structure_General_Device、Pci_Device_Structure_Pci_to_Pci_Bridge、Pci_Device_Structure_Pci_to_Cardbus_Bridge +pub trait PciDeviceStructure: Send + Sync { + /// @brief 获取设备类型 + /// @return HeaderType 设备类型 + fn header_type(&self) -> HeaderType; + /// @brief 当其为standard设备时返回&Pci_Device_Structure_General_Device,其余情况返回None + fn as_standard_device(&self) -> Option<&PciDeviceStructureGeneralDevice> { + None + } + /// @brief 当其为pci to pci bridge设备时返回&Pci_Device_Structure_Pci_to_Pci_Bridge,其余情况返回None + fn as_pci_to_pci_bridge_device(&self) -> Option<&PciDeviceStructurePciToPciBridge> { + None + } + /// @brief 当其为pci to cardbus bridge设备时返回&Pci_Device_Structure_Pci_to_Cardbus_Bridge,其余情况返回None + fn as_pci_to_carbus_bridge_device(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> { + None + } + /// @brief 获取Pci设备共有的common_header + /// @return 返回其不可变引用 + fn common_header(&self) -> &PciDeviceStructureHeader; + /// @brief 当其为standard设备时返回&mut Pci_Device_Structure_General_Device,其余情况返回None + fn as_standard_device_mut(&mut self) -> Option<&mut PciDeviceStructureGeneralDevice> { + None + } + /// @brief 当其为pci to pci bridge设备时返回&mut Pci_Device_Structure_Pci_to_Pci_Bridge,其余情况返回None + fn as_pci_to_pci_bridge_device_mut(&mut self) -> Option<&mut PciDeviceStructurePciToPciBridge> { + None + } + /// @brief 当其为pci to cardbus bridge设备时返回&mut Pci_Device_Structure_Pci_to_Cardbus_Bridge,其余情况返回None + fn as_pci_to_carbus_bridge_device_mut( + &mut self, + ) -> Option<&mut PciDeviceStructurePciToCardbusBridge> { + None + } + /// @brief 返回迭代器,遍历capabilities + fn capabilities(&self) -> Option { + None + } + /// @brief 获取Status、Command寄存器的值 + fn status_command(&self) -> (Status, Command) { + let common_header = self.common_header(); + let status = Status::from_bits_truncate(common_header.status); + let command = Command::from_bits_truncate(common_header.command); + (status, command) + } + /// @brief 设置Command寄存器的值 + fn set_command(&mut self, command: Command) { + let common_header = self.common_header_mut(); + let command = command.bits(); + common_header.command = command; + PciArch::write_config( + &common_header.bus_device_function, STATUS_COMMAND_OFFSET, + command as u32, ); - Status::from_bits_truncate((temp >> 16) as u16) - }; - if status.contains(Status::CAPABILITIES_LIST) { - let cap_pointer = unsafe { - let temp = pci_read_config( - device_function.bus, - device_function.device, - device_function.function, - 0x34, + } + /// @brief 获取Pci设备共有的common_header + /// @return 返回其可变引用 + fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader; + /// @brief 读取standard设备的bar寄存器,映射后将结果加入结构体的standard_device_bar变量 + /// @return 只有standard设备才返回成功或者错误,其余返回None + fn bar_init(&mut self) -> Option> { + None + } + /// todo + fn msix_init(&mut self) -> Option> { + None + } + fn enable_master(&mut self) { + self.set_command(Command::IO_SPACE | Command::MEMORY_SPACE | Command::BUS_MASTER); + } +} + +/// Pci_Device_Structure_Header PCI设备结构体共有的头部 +#[derive(Clone, Debug)] +pub struct PciDeviceStructureHeader { + // 包含msix table地址的bar的mmio基地址 todo:以下四个作为一个结构体统一管理 + pub msix_mmio_vaddr: u64, + pub msix_mmio_size: u64, // msix映射长度 + pub msix_offset: u32, // msix表的offset + pub msix_table_size: u16, // msix表的表项数量 + // ==== busdevicefunction变量表示该结构体所处的位置 + pub bus_device_function: BusDeviceFunction, + pub vendor_id: u16, // 供应商ID 0xffff是一个无效值,在读取访问不存在的设备的配置空间寄存器时返回 + pub device_id: u16, // 设备ID,标志特定设备 + pub command: u16, // 提供对设备生成和响应pci周期的能力的控制 向该寄存器写入0时,设备与pci总线断开除配置空间访问以外的所有连接 + pub status: u16, // 用于记录pci总线相关时间的状态信息寄存器 + pub revision_id: u8, // 修订ID,指定特定设备的修订标志符 + pub prog_if: u8, // 编程接口字节,一个只读寄存器,指定设备具有的寄存器级别的编程接口(如果有的话) + pub subclass: u8, // 子类。指定设备执行的特定功能的只读寄存器 + pub class_code: u8, // 类代码,一个只读寄存器,指定设备执行的功能类型 + pub cache_line_size: u8, // 缓存线大小:以 32 位为单位指定系统缓存线大小。设备可以限制它可以支持的缓存线大小的数量,如果不支持的值写入该字段,设备将表现得好像写入了 0 值 + pub latency_timer: u8, // 延迟计时器:以 PCI 总线时钟为单位指定延迟计时器。 + pub header_type: u8, // 标头类型 a value of 0x0 specifies a general device, a value of 0x1 specifies a PCI-to-PCI bridge, and a value of 0x2 specifies a CardBus bridge. If bit 7 of this register is set, the device has multiple functions; otherwise, it is a single function device. + pub bist: u8, // Represents that status and allows control of a devices BIST (built-in self test). + // Here is the layout of the BIST register: + // | bit7 | bit6 | Bits 5-4 | Bits 3-0 | + // | BIST Capable | Start BIST | Reserved | Completion Code | + // for more details, please visit https://wiki.osdev.org/PCI +} + +/// Pci_Device_Structure_General_Device PCI标准设备结构体 +#[derive(Clone, Debug)] +pub struct PciDeviceStructureGeneralDevice { + pub common_header: PciDeviceStructureHeader, + pub standard_device_bar: PciStandardDeviceBar, + pub cardbus_cis_pointer: u32, // 指向卡信息结构,供在 CardBus 和 PCI 之间共享芯片的设备使用。 + pub subsystem_vendor_id: u16, + pub subsystem_id: u16, + pub expansion_rom_base_address: u32, + pub capabilities_pointer: u8, + pub reserved0: u8, + pub reserved1: u16, + pub reserved2: u32, + pub interrupt_line: u8, // 指定设备的中断引脚连接到系统中断控制器的哪个输入,并由任何使用中断引脚的设备实现。对于 x86 架构,此寄存器对应于 PIC IRQ 编号 0-15(而不是 I/O APIC IRQ 编号),并且值0xFF定义为无连接。 + pub interrupt_pin: u8, // 指定设备使用的中断引脚。其中值为0x1INTA#、0x2INTB#、0x3INTC#、0x4INTD#,0x0表示设备不使用中断引脚。 + pub min_grant: u8, // 一个只读寄存器,用于指定设备所需的突发周期长度(以 1/4 微秒为单位)(假设时钟速率为 33 MHz) + pub max_latency: u8, // 一个只读寄存器,指定设备需要多长时间访问一次 PCI 总线(以 1/4 微秒为单位)。 +} +impl PciDeviceStructure for PciDeviceStructureGeneralDevice { + fn header_type(&self) -> HeaderType { + HeaderType::Standard + } + fn as_standard_device(&self) -> Option<&PciDeviceStructureGeneralDevice> { + Some(self) + } + fn as_standard_device_mut(&mut self) -> Option<&mut PciDeviceStructureGeneralDevice> { + Some(self) + } + fn common_header(&self) -> &PciDeviceStructureHeader { + &self.common_header + } + + fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader { + &mut self.common_header + } + fn capabilities(&self) -> Option { + Some(CapabilityIterator { + bus_device_function: self.common_header.bus_device_function, + next_capability_offset: Some(self.capabilities_pointer), + }) + } + fn bar_init(&mut self) -> Option> { + let common_header = &self.common_header; + match pci_bar_init(common_header.bus_device_function) { + Ok(bar) => { + self.standard_device_bar = bar; + Some(Ok(0)) + } + Err(e) => Some(Err(e)), + } + } +} +/// Pci_Device_Structure_Pci_to_Pci_Bridge pci-to-pci桥设备结构体 +#[derive(Clone, Debug)] +pub struct PciDeviceStructurePciToPciBridge { + pub common_header: PciDeviceStructureHeader, + pub bar0: u32, + pub bar1: u32, + pub primary_bus_number: u8, + pub secondary_bus_number: u8, + pub subordinate_bus_number: u8, + pub secondary_latency_timer: u8, + pub io_base: u8, + pub io_limit: u8, + pub secondary_status: u16, + pub memory_base: u16, + pub memory_limit: u16, + pub prefetchable_memory_base: u16, + pub prefetchable_memory_limit: u16, + pub prefetchable_base_upper_32_bits: u32, + pub prefetchable_limit_upper_32_bits: u32, + pub io_base_upper_16_bits: u16, + pub io_limit_upper_16_bits: u16, + pub capability_pointer: u8, + pub reserved0: u8, + pub reserved1: u16, + pub expansion_rom_base_address: u32, + pub interrupt_line: u8, + pub interrupt_pin: u8, + pub bridge_control: u16, +} +impl PciDeviceStructure for PciDeviceStructurePciToPciBridge { + fn header_type(&self) -> HeaderType { + HeaderType::PciPciBridge + } + fn as_pci_to_pci_bridge_device(&self) -> Option<&PciDeviceStructurePciToPciBridge> { + Some(self) + } + fn as_pci_to_pci_bridge_device_mut(&mut self) -> Option<&mut PciDeviceStructurePciToPciBridge> { + Some(self) + } + fn common_header(&self) -> &PciDeviceStructureHeader { + &self.common_header + } + + fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader { + &mut self.common_header + } +} +/// Pci_Device_Structure_Pci_to_Cardbus_Bridge Pci_to_Cardbus桥设备结构体 +#[derive(Clone, Debug)] +pub struct PciDeviceStructurePciToCardbusBridge { + pub common_header: PciDeviceStructureHeader, + pub cardbus_socket_ex_ca_base_address: u32, + pub offset_of_capabilities_list: u8, + pub reserved: u8, + pub secondary_status: u16, + pub pci_bus_number: u8, + pub card_bus_bus_number: u8, + pub subordinate_bus_number: u8, + pub card_bus_latency_timer: u8, + pub memory_base_address0: u32, + pub memory_limit0: u32, + pub memory_base_address1: u32, + pub memory_limit1: u32, + pub io_base_address0: u32, + pub io_limit0: u32, + pub io_base_address1: u32, + pub io_limit1: u32, + pub interrupt_line: u8, + pub interrupt_pin: u8, + pub bridge_control: u16, + pub subsystem_device_id: u16, + pub subsystem_vendor_id: u16, + pub pc_card_legacy_mode_base_address_16_bit: u32, +} +impl PciDeviceStructure for PciDeviceStructurePciToCardbusBridge { + fn header_type(&self) -> HeaderType { + HeaderType::PciCardbusBridge + } + fn as_pci_to_carbus_bridge_device(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> { + Some(&self) + } + fn as_pci_to_carbus_bridge_device_mut( + &mut self, + ) -> Option<&mut PciDeviceStructurePciToCardbusBridge> { + Some(self) + } + fn common_header(&self) -> &PciDeviceStructureHeader { + &self.common_header + } + + fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader { + &mut self.common_header + } +} + +/// 代表一个PCI segement greoup. +#[derive(Copy, Clone, Debug, PartialEq)] +pub struct PciRoot { + pub physical_address_base: u64, //物理地址,acpi获取 + pub mmio_base: Option<*mut u32>, //映射后的虚拟地址,为方便访问数据这里转化成指针 + pub segement_group_number: SegmentGroupNumber, //segement greoup的id + pub bus_begin: u8, //该分组中的最小bus + pub bus_end: u8, //该分组中的最大bus +} +///线程间共享需要,该结构体只需要在初始化时写入数据,无需读写锁保证线程安全 +unsafe impl Send for PciRoot {} +unsafe impl Sync for PciRoot {} +///实现PciRoot的Display trait,自定义输出 +impl Display for PciRoot { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!( + f, + "PCI Root with segement:{}, bus begin at {}, bus end at {}, physical address at {},mapped at {:#x}", + self.segement_group_number, self.bus_begin, self.bus_end, self.physical_address_base, self.mmio_base.unwrap() as usize + ) + } +} + +impl PciRoot { + /// @brief 初始化结构体,获取ecam root所在物理地址后map到虚拟地址,再将该虚拟地址加入mmio_base变量 + /// @return 成功返回结果,错误返回错误类型 + pub fn new(segment_group_number: SegmentGroupNumber) -> Result { + let mut pci_root = PciArch::ecam_root(segment_group_number)?; + pci_root.map()?; + Ok(pci_root) + } + /// @brief 完成物理地址到虚拟地址的映射,并将虚拟地址加入mmio_base变量 + /// @return 返回错误或Ok(0) + fn map(&mut self) -> Result { + let bus_number = self.bus_end - self.bus_begin + 1; + let bus_number_double = (bus_number + 1) / 2; + let mut virtaddress: u64 = 0; + let vaddr_ptr = &mut virtaddress as *mut u64; + let mut virtsize: u64 = 0; + let virtsize_ptr = &mut virtsize as *mut u64; + let size = bus_number_double as u32 * PAGE_2M_SIZE; + unsafe { + let initial_mm_ptr = &mut initial_mm as *mut mm_struct; + if let Err(_) = + MMIO_POOL.create_mmio(size, (VM_IO | VM_DONTCOPY) as u64, vaddr_ptr, virtsize_ptr) + { + kerror!("Create mmio failed when initing ecam"); + return Err(PciError::CreateMmioError); + }; + //kdebug!("virtaddress={:#x},virtsize={:#x}",virtaddress,virtsize); + mm_map( + initial_mm_ptr, + virtaddress, + size as u64, + self.physical_address_base, ); - temp as u8 & 0xFC - }; + } + self.mmio_base = Some(virtaddress as *mut u32); + Ok(0) + } + /// @brief 获得要操作的寄存器相对于mmio_offset的偏移量 + /// @param bus_device_function 在同一个group中pci设备的唯一标识符 + /// @param register_offset 寄存器在设备中的offset + /// @return u32 要操作的寄存器相对于mmio_offset的偏移量 + fn cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 { + assert!(bus_device_function.valid()); + let bdf = ((bus_device_function.bus - self.bus_begin) as u32) << 8 + | (bus_device_function.device as u32) << 3 + | bus_device_function.function as u32; + let address = bdf << 12 | register_offset as u32; + // Ensure that address is word-aligned. + assert!(address & 0x3 == 0); + address + } + /// @brief 通过bus_device_function和offset读取相应位置寄存器的值(32位) + /// @param bus_device_function 在同一个group中pci设备的唯一标识符 + /// @param register_offset 寄存器在设备中的offset + /// @return u32 寄存器读值结果 + pub fn read_config( + &self, + bus_device_function: BusDeviceFunction, + register_offset: u16, + ) -> u32 { + let address = self.cam_offset(bus_device_function, register_offset); + unsafe { + // Right shift to convert from byte offset to word offset. + (self.mmio_base.unwrap().add((address >> 2) as usize)).read_volatile() + } + } + + /// @brief 通过bus_device_function和offset写入相应位置寄存器值(32位) + /// @param bus_device_function 在同一个group中pci设备的唯一标识符 + /// @param register_offset 寄存器在设备中的offset + /// @param data 要写入的值 + pub fn write_config( + &mut self, + bus_device_function: BusDeviceFunction, + register_offset: u16, + data: u32, + ) { + let address = self.cam_offset(bus_device_function, register_offset); + // Safe because both the `mmio_base` and the address offset are properly aligned, and the + // resulting pointer is within the MMIO range of the CAM. + unsafe { + // Right shift to convert from byte offset to word offset. + (self.mmio_base.unwrap().add((address >> 2) as usize)).write_volatile(data) + } + } + /// @brief 返回迭代器,遍历pcie设备的external_capabilities + pub fn external_capabilities( + &self, + bus_device_function: BusDeviceFunction, + ) -> ExternalCapabilityIterator { + ExternalCapabilityIterator { + root: self, + bus_device_function, + next_capability_offset: Some(0x100), + } + } +} +/// Gets the capabilities 'pointer' for the device function, if any. +/// @brief 获取第一个capability 的offset +/// @param bus_device_function PCI设备的唯一标识 +/// @return Option offset +pub fn capabilities_offset(bus_device_function: BusDeviceFunction) -> Option { + let result = PciArch::read_config(&bus_device_function, STATUS_COMMAND_OFFSET); + let status: Status = Status::from_bits_truncate((result >> 16) as u16); + if status.contains(Status::CAPABILITIES_LIST) { + let cap_pointer = PciArch::read_config(&bus_device_function, 0x34) as u8 & 0xFC; Some(cap_pointer) } else { None } } + +/// @brief 读取pci设备头部 +/// @param bus_device_function PCI设备的唯一标识 +/// @param add_to_list 是否添加到链表 +/// @return 返回的header(trait 类型) +fn pci_read_header( + bus_device_function: BusDeviceFunction, + add_to_list: bool, +) -> Result, PciError> { + // 先读取公共header + let result = PciArch::read_config(&bus_device_function, 0x00); + let vendor_id = result as u16; + let device_id = (result >> 16) as u16; + + let result = PciArch::read_config(&bus_device_function, 0x04); + let command = result as u16; + let status = (result >> 16) as u16; + + let result = PciArch::read_config(&bus_device_function, 0x08); + let revision_id = result as u8; + let prog_if = (result >> 8) as u8; + let subclass = (result >> 16) as u8; + let class_code = (result >> 24) as u8; + + let result = PciArch::read_config(&bus_device_function, 0x0c); + let cache_line_size = result as u8; + let latency_timer = (result >> 8) as u8; + let header_type = (result >> 16) as u8; + let bist = (result >> 24) as u8; + if vendor_id == 0xffff { + return Err(PciError::GetWrongHeader); + } + let header = PciDeviceStructureHeader { + msix_mmio_vaddr: 0, + msix_mmio_size: 0, + msix_offset: 0, + msix_table_size: 0, + bus_device_function, + vendor_id, + device_id, + command, + status, + revision_id, + prog_if, + subclass, + class_code, + cache_line_size, + latency_timer, + header_type, + bist, + }; + match HeaderType::from(header_type & 0x7f) { + HeaderType::Standard => { + let general_device = pci_read_general_device_header(header, &bus_device_function); + let box_general_device = Box::new(general_device); + let box_general_device_clone = box_general_device.clone(); + if add_to_list { + PCI_DEVICE_LINKEDLIST.add(box_general_device); + } + Ok(box_general_device_clone) + } + HeaderType::PciPciBridge => { + let pci_to_pci_bridge = pci_read_pci_to_pci_bridge_header(header, &bus_device_function); + let box_pci_to_pci_bridge = Box::new(pci_to_pci_bridge); + let box_pci_to_pci_bridge_clone = box_pci_to_pci_bridge.clone(); + if add_to_list { + PCI_DEVICE_LINKEDLIST.add(box_pci_to_pci_bridge); + } + Ok(box_pci_to_pci_bridge_clone) + } + HeaderType::PciCardbusBridge => { + let pci_cardbus_bridge = + pci_read_pci_to_cardbus_bridge_header(header, &bus_device_function); + let box_pci_cardbus_bridge = Box::new(pci_cardbus_bridge); + let box_pci_cardbus_bridge_clone = box_pci_cardbus_bridge.clone(); + if add_to_list { + PCI_DEVICE_LINKEDLIST.add(box_pci_cardbus_bridge); + } + Ok(box_pci_cardbus_bridge_clone) + } + HeaderType::Unrecognised(_) => Err(PciError::UnrecognisedHeaderType), + } +} + +/// @brief 读取type为0x0的pci设备的header +/// 本函数只应被 pci_read_header()调用 +/// @param common_header 共有头部 +/// @param bus_device_function PCI设备的唯一标识 +/// @return Pci_Device_Structure_General_Device 标准设备头部 +fn pci_read_general_device_header( + common_header: PciDeviceStructureHeader, + bus_device_function: &BusDeviceFunction, +) -> PciDeviceStructureGeneralDevice { + let standard_device_bar = PciStandardDeviceBar::default(); + let cardbus_cis_pointer = PciArch::read_config(bus_device_function, 0x28); + + let result = PciArch::read_config(bus_device_function, 0x2c); + let subsystem_vendor_id = result as u16; + let subsystem_id = (result >> 16) as u16; + + let expansion_rom_base_address = PciArch::read_config(bus_device_function, 0x30); + + let result = PciArch::read_config(bus_device_function, 0x34); + let capabilities_pointer = result as u8; + let reserved0 = (result >> 8) as u8; + let reserved1 = (result >> 16) as u16; + + let reserved2 = PciArch::read_config(bus_device_function, 0x38); + + let result = PciArch::read_config(bus_device_function, 0x3c); + let interrupt_line = result as u8; + let interrupt_pin = (result >> 8) as u8; + let min_grant = (result >> 16) as u8; + let max_latency = (result >> 24) as u8; + PciDeviceStructureGeneralDevice { + common_header, + standard_device_bar, + cardbus_cis_pointer, + subsystem_vendor_id, + subsystem_id, + expansion_rom_base_address, + capabilities_pointer, + reserved0, + reserved1, + reserved2, + interrupt_line, + interrupt_pin, + min_grant, + max_latency, + } +} + +/// @brief 读取type为0x1的pci设备的header +/// 本函数只应被 pci_read_header()调用 +/// @param common_header 共有头部 +/// @param bus_device_function PCI设备的唯一标识 +/// @return Pci_Device_Structure_Pci_to_Pci_Bridge pci-to-pci 桥设备头部 +fn pci_read_pci_to_pci_bridge_header( + common_header: PciDeviceStructureHeader, + bus_device_function: &BusDeviceFunction, +) -> PciDeviceStructurePciToPciBridge { + let bar0 = PciArch::read_config(bus_device_function, 0x10); + let bar1 = PciArch::read_config(bus_device_function, 0x14); + + let result = PciArch::read_config(bus_device_function, 0x18); + + let primary_bus_number = result as u8; + let secondary_bus_number = (result >> 8) as u8; + let subordinate_bus_number = (result >> 16) as u8; + let secondary_latency_timer = (result >> 24) as u8; + + let result = PciArch::read_config(bus_device_function, 0x1c); + let io_base = result as u8; + let io_limit = (result >> 8) as u8; + let secondary_status = (result >> 16) as u16; + + let result = PciArch::read_config(bus_device_function, 0x20); + let memory_base = result as u16; + let memory_limit = (result >> 16) as u16; + + let result = PciArch::read_config(bus_device_function, 0x24); + let prefetchable_memory_base = result as u16; + let prefetchable_memory_limit = (result >> 16) as u16; + + let prefetchable_base_upper_32_bits = PciArch::read_config(bus_device_function, 0x28); + let prefetchable_limit_upper_32_bits = PciArch::read_config(bus_device_function, 0x2c); + + let result = PciArch::read_config(bus_device_function, 0x30); + let io_base_upper_16_bits = result as u16; + let io_limit_upper_16_bits = (result >> 16) as u16; + + let result = PciArch::read_config(bus_device_function, 0x34); + let capability_pointer = result as u8; + let reserved0 = (result >> 8) as u8; + let reserved1 = (result >> 16) as u16; + + let expansion_rom_base_address = PciArch::read_config(bus_device_function, 0x38); + + let result = PciArch::read_config(bus_device_function, 0x3c); + let interrupt_line = result as u8; + let interrupt_pin = (result >> 8) as u8; + let bridge_control = (result >> 16) as u16; + PciDeviceStructurePciToPciBridge { + common_header, + bar0, + bar1, + primary_bus_number, + secondary_bus_number, + subordinate_bus_number, + secondary_latency_timer, + io_base, + io_limit, + secondary_status, + memory_base, + memory_limit, + prefetchable_memory_base, + prefetchable_memory_limit, + prefetchable_base_upper_32_bits, + prefetchable_limit_upper_32_bits, + io_base_upper_16_bits, + io_limit_upper_16_bits, + capability_pointer, + reserved0, + reserved1, + expansion_rom_base_address, + interrupt_line, + interrupt_pin, + bridge_control, + } +} + +/// @brief 读取type为0x2的pci设备的header +/// 本函数只应被 pci_read_header()调用 +/// @param common_header 共有头部 +/// @param bus_device_function PCI设备的唯一标识 +/// @return ) -> Pci_Device_Structure_Pci_to_Cardbus_Bridge pci-to-cardbus 桥设备头部 +fn pci_read_pci_to_cardbus_bridge_header( + common_header: PciDeviceStructureHeader, + busdevicefunction: &BusDeviceFunction, +) -> PciDeviceStructurePciToCardbusBridge { + let cardbus_socket_ex_ca_base_address = PciArch::read_config(busdevicefunction, 0x10); + + let result = PciArch::read_config(busdevicefunction, 0x14); + let offset_of_capabilities_list = result as u8; + let reserved = (result >> 8) as u8; + let secondary_status = (result >> 16) as u16; + + let result = PciArch::read_config(busdevicefunction, 0x18); + let pci_bus_number = result as u8; + let card_bus_bus_number = (result >> 8) as u8; + let subordinate_bus_number = (result >> 16) as u8; + let card_bus_latency_timer = (result >> 24) as u8; + + let memory_base_address0 = PciArch::read_config(busdevicefunction, 0x1c); + let memory_limit0 = PciArch::read_config(busdevicefunction, 0x20); + let memory_base_address1 = PciArch::read_config(busdevicefunction, 0x24); + let memory_limit1 = PciArch::read_config(busdevicefunction, 0x28); + + let io_base_address0 = PciArch::read_config(busdevicefunction, 0x2c); + let io_limit0 = PciArch::read_config(busdevicefunction, 0x30); + let io_base_address1 = PciArch::read_config(busdevicefunction, 0x34); + let io_limit1 = PciArch::read_config(busdevicefunction, 0x38); + let result = PciArch::read_config(busdevicefunction, 0x3c); + let interrupt_line = result as u8; + let interrupt_pin = (result >> 8) as u8; + let bridge_control = (result >> 16) as u16; + + let result = PciArch::read_config(busdevicefunction, 0x40); + let subsystem_device_id = result as u16; + let subsystem_vendor_id = (result >> 16) as u16; + + let pc_card_legacy_mode_base_address_16_bit = PciArch::read_config(busdevicefunction, 0x44); + PciDeviceStructurePciToCardbusBridge { + common_header, + cardbus_socket_ex_ca_base_address, + offset_of_capabilities_list, + reserved, + secondary_status, + pci_bus_number, + card_bus_bus_number, + subordinate_bus_number, + card_bus_latency_timer, + memory_base_address0, + memory_limit0, + memory_base_address1, + memory_limit1, + io_base_address0, + io_limit0, + io_base_address1, + io_limit1, + interrupt_line, + interrupt_pin, + bridge_control, + subsystem_device_id, + subsystem_vendor_id, + pc_card_legacy_mode_base_address_16_bit, + } +} + +/// @brief 检查所有bus上的设备并将其加入链表 +/// @return 成功返回ok(),失败返回失败原因 +fn pci_check_all_buses() -> Result { + kinfo!("Checking all devices in PCI bus..."); + let busdevicefunction = BusDeviceFunction { + bus: 0, + device: 0, + function: 0, + }; + let header = pci_read_header(busdevicefunction, false)?; + let common_header = header.common_header(); + pci_check_bus(0)?; + if common_header.header_type & 0x80 != 0 { + for function in 1..8 { + pci_check_bus(function)?; + } + } + Ok(0) +} +/// @brief 检查特定设备并将其加入链表 +/// @return 成功返回ok(),失败返回失败原因 +fn pci_check_function(busdevicefunction: BusDeviceFunction) -> Result { + //kdebug!("PCI check function {}", busdevicefunction.function); + let header = match pci_read_header(busdevicefunction, true) { + Ok(header) => header, + Err(PciError::GetWrongHeader) => { + return Ok(255); + } + Err(e) => { + return Err(e); + } + }; + let common_header = header.common_header(); + if (common_header.class_code == 0x06) + && (common_header.subclass == 0x04 || common_header.subclass == 0x09) + { + let pci_to_pci_bridge = header + .as_pci_to_pci_bridge_device() + .ok_or(PciError::PciDeviceStructureTransformError)?; + let secondary_bus = pci_to_pci_bridge.secondary_bus_number; + pci_check_bus(secondary_bus)?; + } + Ok(0) +} + +/// @brief 检查device上的设备并将其加入链表 +/// @return 成功返回ok(),失败返回失败原因 +fn pci_check_device(bus: u8, device: u8) -> Result { + //kdebug!("PCI check device {}", device); + let busdevicefunction = BusDeviceFunction { + bus, + device, + function: 0, + }; + let header = match pci_read_header(busdevicefunction, false) { + Ok(header) => header, + Err(PciError::GetWrongHeader) => { + //设备不存在,直接返回即可,不用终止遍历 + return Ok(255); + } + Err(e) => { + return Err(e); + } + }; + pci_check_function(busdevicefunction)?; + let common_header = header.common_header(); + if common_header.header_type & 0x80 != 0 { + kdebug!( + "Detected multi func device in bus{},device{}", + busdevicefunction.bus, + busdevicefunction.device + ); + // 这是一个多function的设备,因此查询剩余的function + for function in 1..8 { + let busdevicefunction = BusDeviceFunction { + bus, + device, + function, + }; + pci_check_function(busdevicefunction)?; + } + } + Ok(0) +} +/// @brief 检查该bus上的设备并将其加入链表 +/// @return 成功返回ok(),失败返回失败原因 +fn pci_check_bus(bus: u8) -> Result { + //kdebug!("PCI check bus {}", bus); + for device in 0..32 { + pci_check_device(bus, device)?; + } + Ok(0) +} +/// @brief pci初始化函数(for c) +#[no_mangle] +pub extern "C" fn rs_pci_init() { + pci_init(); + //kdebug!("{}",PCI_ROOT_0.unwrap()); +} +/// @brief pci初始化函数 +pub fn pci_init() { + kinfo!("Initializing PCI bus..."); + if let Err(e) = pci_check_all_buses() { + kerror!("pci init failed when checking bus because of error: {}", e); + return; + } + kinfo!( + "Total pci device and function num = {}", + PCI_DEVICE_LINKEDLIST.num() + ); + let list = PCI_DEVICE_LINKEDLIST.read(); + for box_pci_device in list.iter() { + let common_header = box_pci_device.common_header(); + match box_pci_device.header_type() { + HeaderType::Standard if common_header.status & 0x10 != 0 => { + kinfo!("Found pci standard device with class code ={} subclass={} status={:#x} cap_pointer={:#x} vendor={:#x}, device id={:#x}", common_header.class_code, common_header.subclass, common_header.status, box_pci_device.as_standard_device().unwrap().capabilities_pointer,common_header.vendor_id, common_header.device_id); + } + HeaderType::Standard => { + kinfo!( + "Found pci standard device with class code ={} subclass={} status={:#x} ", + common_header.class_code, + common_header.subclass, + common_header.status + ); + } + HeaderType::PciPciBridge if common_header.status & 0x10 != 0 => { + kinfo!("Found pci-to-pci bridge device with class code ={} subclass={} status={:#x} cap_pointer={:#x}", common_header.class_code, common_header.subclass, common_header.status, box_pci_device.as_standard_device().unwrap().capabilities_pointer); + } + HeaderType::PciPciBridge => { + kinfo!( + "Found pci-to-pci bridge device with class code ={} subclass={} status={:#x} ", + common_header.class_code, + common_header.subclass, + common_header.status + ); + } + HeaderType::PciCardbusBridge => { + kinfo!( + "Found pcicardbus bridge device with class code ={} subclass={} status={:#x} ", + common_header.class_code, + common_header.subclass, + common_header.status + ); + } + HeaderType::Unrecognised(_) => {} + } + } + kinfo!("PCI bus initialized."); +} + /// An identifier for a PCI bus, device and function. /// PCI设备的唯一标识 #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct DeviceFunction { +pub struct BusDeviceFunction { /// The PCI bus number, between 0 and 255. pub bus: u8, /// The device number on the bus, between 0 and 31. @@ -111,36 +1050,18 @@ pub struct DeviceFunction { /// The function number of the device, between 0 and 7. pub function: u8, } -///PCI的Error -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum PciError { - /// The device reported an invalid BAR type. - InvalidBarType, - CreateMmioError, -} -///实现PciError的Display trait,使其可以直接输出 -impl Display for PciError { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - Self::InvalidBarType => write!(f, "Invalid PCI BAR type."), - Self::CreateMmioError => write!(f, "Error occurred while creating mmio"), - } - } -} - -impl DeviceFunction { +impl BusDeviceFunction { /// Returns whether the device and function numbers are valid, i.e. the device is between 0 and - /// 31, and the function is between 0 and 7. - /// @brief 检测DeviceFunction实例是否有效 - /// @param self - /// @return bool 是否有效 + ///@brief 检测BusDeviceFunction实例是否有效 + ///@param self + ///@return bool 是否有效 #[allow(dead_code)] pub fn valid(&self) -> bool { self.device < 32 && self.function < 8 } } -///实现DeviceFunction的Display trait,使其可以直接输出 -impl Display for DeviceFunction { +///实现BusDeviceFunction的Display trait,使其可以直接输出 +impl Display for BusDeviceFunction { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{:02x}:{:02x}.{}", self.bus, self.device, self.function) } @@ -231,7 +1152,7 @@ impl BarInfo { } } } -///实现BarInfo的Display trait,使其可以直接输出 +///实现BarInfo的Display trait,自定义输出 impl Display for BarInfo { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { @@ -255,9 +1176,9 @@ impl Display for BarInfo { } } } -///一个PCI设备有6个BAR寄存器,PciDeviceBar存储其全部信息 +///一个普通PCI设备(非桥)有6个BAR寄存器,PciStandardDeviceBar存储其全部信息 #[derive(Clone, Debug, Eq, PartialEq)] -pub struct PciDeviceBar { +pub struct PciStandardDeviceBar { bar0: BarInfo, bar1: BarInfo, bar2: BarInfo, @@ -266,7 +1187,7 @@ pub struct PciDeviceBar { bar5: BarInfo, } -impl PciDeviceBar { +impl PciStandardDeviceBar { ///@brief 得到某个bar的barinfo ///@param self ,bar_index(0-5) ///@return Result<&BarInfo, PciError> bar_index在0-5则返回对应的bar_info结构体,超出范围则返回错误 @@ -277,12 +1198,13 @@ impl PciDeviceBar { 2 => Ok(&self.bar2), 3 => Ok(&self.bar3), 4 => Ok(&self.bar4), + 5 => Ok(&self.bar5), _ => Err(PciError::InvalidBarType), } } } -///实现PciDeviceBar的Display trait,使其可以直接输出 -impl Display for PciDeviceBar { +///实现PciStandardDeviceBar的Display trait,使其可以直接输出 +impl Display for PciStandardDeviceBar { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!( f, @@ -291,10 +1213,10 @@ impl Display for PciDeviceBar { ) } } -///实现PciDeviceBar的Default trait,使其可以简单初始化 -impl Default for PciDeviceBar { +///实现PciStandardDeviceBar的Default trait,使其可以简单初始化 +impl Default for PciStandardDeviceBar { fn default() -> Self { - PciDeviceBar { + PciStandardDeviceBar { bar0: BarInfo::Unused, bar1: BarInfo::Unused, bar2: BarInfo::Unused, @@ -305,11 +1227,13 @@ impl Default for PciDeviceBar { } } -///@brief 将某个pci设备的bar全部初始化,memory -///@param self ,device_function PCI设备的唯一标识符 -///@return Result 成功则返回对应的PciDeviceBar结构体,失败则返回错误类型 -pub fn pci_bar_init(device_function: DeviceFunction) -> Result { - let mut device_bar: PciDeviceBar = PciDeviceBar::default(); +///@brief 将某个pci设备的bar寄存器读取值后映射到虚拟地址 +///@param self ,bus_device_function PCI设备的唯一标识符 +///@return Result 成功则返回对应的PciStandardDeviceBar结构体,失败则返回错误类型 +pub fn pci_bar_init( + bus_device_function: BusDeviceFunction, +) -> Result { + let mut device_bar: PciStandardDeviceBar = PciStandardDeviceBar::default(); let mut bar_index_ignore: u8 = 255; for bar_index in 0..6 { if bar_index == bar_index_ignore { @@ -317,47 +1241,19 @@ pub fn pci_bar_init(device_function: DeviceFunction) -> Result Result= 5 { return Err(PciError::InvalidBarType); } - let address_top = unsafe { - let bar_temp = pci_read_config( - device_function.bus, - device_function.device, - device_function.function, - BAR0_OFFSET + 4 * (bar_index + 1), - ); - bar_temp - }; + let address_top = + PciArch::read_config(&bus_device_function, BAR0_OFFSET + 4 * (bar_index + 1)); address |= u64::from(address_top) << 32; bar_index_ignore = bar_index + 1; //下个bar跳过,因为64位的memory bar覆盖了两个bar } @@ -455,7 +1344,7 @@ pub struct CapabilityInfo { /// 创建迭代器以遍历PCI设备的capability #[derive(Debug)] pub struct CapabilityIterator { - pub device_function: DeviceFunction, + pub bus_device_function: BusDeviceFunction, pub next_capability_offset: Option, } @@ -465,15 +1354,7 @@ impl Iterator for CapabilityIterator { let offset = self.next_capability_offset?; // Read the first 4 bytes of the capability. - let capability_header = unsafe { - let temp = pci_read_config( - self.device_function.bus, - self.device_function.device, - self.device_function.function, - offset, - ); - temp - }; + let capability_header = PciArch::read_config(&self.bus_device_function, offset); let id = capability_header as u8; let next_offset = (capability_header >> 8) as u8; let private_header = (capability_header >> 16) as u16; @@ -495,27 +1376,50 @@ impl Iterator for CapabilityIterator { } } -/// @brief 设置PCI Config Space里面的Command Register -/// -/// @param device_function 设备 -/// @param value command register要被设置成的值 -pub fn set_command_register(device_function: &DeviceFunction, value: CommandRegister) { - unsafe { - pci_write_config( - device_function.bus, - device_function.device, - device_function.function, - STATUS_COMMAND_OFFSET, - value.bits().into(), - ); +/// Information about a PCIe device capability. +/// PCIe设备的external capability的信息 +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct ExternalCapabilityInfo { + /// The offset of the capability in the PCI configuration space of the device function. + pub offset: u16, + /// The ID of the capability. + pub id: u16, + /// The third and fourth bytes of the capability, to save reading them again. + pub capability_version: u8, +} + +/// Iterator over capabilities for a device. +/// 创建迭代器以遍历PCIe设备的external capability +#[derive(Debug)] +pub struct ExternalCapabilityIterator<'a> { + pub root: &'a PciRoot, + pub bus_device_function: BusDeviceFunction, + pub next_capability_offset: Option, +} +impl<'a> Iterator for ExternalCapabilityIterator<'a> { + type Item = ExternalCapabilityInfo; + fn next(&mut self) -> Option { + let offset = self.next_capability_offset?; + + // Read the first 4 bytes of the capability. + let capability_header = self.root.read_config(self.bus_device_function, offset); + let id = capability_header as u16; + let next_offset = (capability_header >> 20) as u16; + let capability_version = ((capability_header >> 16) & 0xf) as u8; + + self.next_capability_offset = if next_offset == 0 { + None + } else if next_offset < 0x100 || next_offset & 0x3 != 0 { + kwarn!("Invalid next capability offset {:#04x}", next_offset); + None + } else { + Some(next_offset) + }; + + Some(ExternalCapabilityInfo { + offset, + id, + capability_version, + }) } } -/// @brief 使能对PCI Memory/IO空间的写入,使能PCI设备作为主设备(主动进行Memory的写入等,msix中断使用到) -/// -/// @param device_function 设备 -pub fn pci_enable_master(device_function: DeviceFunction) { - set_command_register( - &device_function, - CommandRegister::IO_SPACE | CommandRegister::MEMORY_SPACE | CommandRegister::BUS_MASTER, - ); -} diff --git a/kernel/src/driver/timers/rtc/rtc.rs b/kernel/src/driver/timers/rtc/rtc.rs index 63df25c0..4dd659df 100644 --- a/kernel/src/driver/timers/rtc/rtc.rs +++ b/kernel/src/driver/timers/rtc/rtc.rs @@ -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 { diff --git a/kernel/src/driver/video/mod.rs b/kernel/src/driver/video/mod.rs index 878c0a94..018eab6d 100644 --- a/kernel/src/driver/video/mod.rs +++ b/kernel/src/driver/video/mod.rs @@ -1,23 +1,26 @@ -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; } - + unsafe { video_refresh_framebuffer(null_mut()); } @@ -28,7 +31,7 @@ impl SoftirqVec for VideoRefreshFramebuffer { impl VideoRefreshFramebuffer { pub fn new() -> VideoRefreshFramebuffer { VideoRefreshFramebuffer { - running: AtomicBool::new(false) + running: AtomicBool::new(false), } } diff --git a/kernel/src/driver/virtio/Makefile b/kernel/src/driver/virtio/Makefile deleted file mode 100644 index d7148862..00000000 --- a/kernel/src/driver/virtio/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: virtio.o - -CFLAGS += -I . - -virtio.o: virtio.c - $(CC) $(CFLAGS) -c virtio.c -o virtio.o - diff --git a/kernel/src/driver/virtio/transport_pci.rs b/kernel/src/driver/virtio/transport_pci.rs index 162fb459..676f8e8d 100644 --- a/kernel/src/driver/virtio/transport_pci.rs +++ b/kernel/src/driver/virtio/transport_pci.rs @@ -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, /// 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(device_function: DeviceFunction) -> Result { - 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( + device: &mut PciDeviceStructureGeneralDevice, + ) -> Result { + 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, ¬ify_cfg)?; + let notify_region = get_bar_region_slice::<_>(&device.standard_device_bar, ¬ify_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 for VirtioPciError { ///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息 ///@return Result, VirtioPciError> 成功则返回对应类型的指针,失败则返回Error fn get_bar_region( - device_bar: &PciDeviceBar, + device_bar: &PciStandardDeviceBar, struct_info: &VirtioCapabilityInfo, ) -> Result, VirtioPciError> { let bar_info = device_bar.get_bar(struct_info.bar)?; @@ -521,7 +490,7 @@ fn get_bar_region( ///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息切片的指针 ///@return Result, VirtioPciError> 成功则返回对应类型的指针切片,失败则返回Error fn get_bar_region_slice( - device_bar: &PciDeviceBar, + device_bar: &PciStandardDeviceBar, struct_info: &VirtioCapabilityInfo, ) -> Result, VirtioPciError> { let ptr = get_bar_region::(device_bar, struct_info)?; diff --git a/kernel/src/driver/virtio/virtio.c b/kernel/src/driver/virtio/virtio.c deleted file mode 100644 index 27ec0e88..00000000 --- a/kernel/src/driver/virtio/virtio.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "virtio.h" -#include -#include -#include - -#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; -} \ No newline at end of file diff --git a/kernel/src/driver/virtio/virtio.h b/kernel/src/driver/virtio/virtio.h index 7dc9d54d..2af1ad19 100644 --- a/kernel/src/driver/virtio/virtio.h +++ b/kernel/src/driver/virtio/virtio.h @@ -1,12 +1,5 @@ #pragma once #include -#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(); diff --git a/kernel/src/driver/virtio/virtio.rs b/kernel/src/driver/virtio/virtio.rs index 05e2f053..8843628b 100644 --- a/kernel/src/driver/virtio/virtio.rs +++ b/kernel/src/driver/virtio/virtio.rs @@ -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::(*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::(*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::(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(transport: T) { } /// @brief 寻找所有的virtio设备 -/// @return Result>,VirtioError> 成功则返回包含所有virtio设备的链表,失败则返回err +/// @param list 链表的写锁 +/// @return Result, VirtioError> 成功则返回包含所有virtio设备结构体的可变引用的链表,失败则返回err /// 该函数主要是为其他virtio设备预留支持 -fn virtio_device_search() -> Result>, VirtioError> { - let mut virtio_list: LinkedList> = 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>>, +) -> Result, 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>>, +) -> 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) +} diff --git a/kernel/src/driver/virtio/virtio_impl.rs b/kernel/src/driver/virtio/virtio_impl.rs index 16a48c2d..99a1a293 100644 --- a/kernel/src/driver/virtio/virtio_impl.rs +++ b/kernel/src/driver/virtio/virtio_impl.rs @@ -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; diff --git a/kernel/src/filesystem/devfs/null_dev.rs b/kernel/src/filesystem/devfs/null_dev.rs index bf794928..d31f4609 100644 --- a/kernel/src/filesystem/devfs/null_dev.rs +++ b/kernel/src/filesystem/devfs/null_dev.rs @@ -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}, diff --git a/kernel/src/filesystem/devfs/zero_dev.rs b/kernel/src/filesystem/devfs/zero_dev.rs index 4b91e679..9125d34b 100644 --- a/kernel/src/filesystem/devfs/zero_dev.rs +++ b/kernel/src/filesystem/devfs/zero_dev.rs @@ -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}, diff --git a/kernel/src/filesystem/fat/bpb.rs b/kernel/src/filesystem/fat/bpb.rs index 584dff1f..feb516ff 100644 --- a/kernel/src/filesystem/fat/bpb.rs +++ b/kernel/src/filesystem/fat/bpb.rs @@ -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}; diff --git a/kernel/src/filesystem/fat/entry.rs b/kernel/src/filesystem/fat/entry.rs index bcc69ebc..53b10103 100644 --- a/kernel/src/filesystem/fat/entry.rs +++ b/kernel/src/filesystem/fat/entry.rs @@ -79,7 +79,12 @@ impl FATFile { /// /// @return Ok(usize) 成功读取到的字节数 /// @return Err(SystemError) 读取时出现错误,返回错误码 - pub fn read(&self, fs: &Arc, buf: &mut [u8], offset: u64) -> Result { + pub fn read( + &self, + fs: &Arc, + buf: &mut [u8], + offset: u64, + ) -> Result { 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, offset: u64, len: u64) -> Result<(), SystemError> { + fn ensure_len( + &mut self, + fs: &Arc, + 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, name: &str) -> Result { + pub fn get_dir_entry( + &self, + fs: Arc, + name: &str, + ) -> Result { 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, disk_bytes_offset: u64) -> Result<(), SystemError> { + pub fn flush( + &self, + fs: &Arc, + disk_bytes_offset: u64, + ) -> Result<(), SystemError> { // 从磁盘读取数据 let blk_offset = fs.get_in_block_offset(disk_bytes_offset); let lba = fs.get_lba_from_offset( diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 18e325ce..5b68ff74 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -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 { diff --git a/kernel/src/filesystem/procfs/mod.rs b/kernel/src/filesystem/procfs/mod.rs index 08122c43..b221c84f 100644 --- a/kernel/src/filesystem/procfs/mod.rs +++ b/kernel/src/filesystem/procfs/mod.rs @@ -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 进程文件类型 diff --git a/kernel/src/filesystem/ramfs/mod.rs b/kernel/src/filesystem/ramfs/mod.rs index 026734b0..e087095a 100644 --- a/kernel/src/filesystem/ramfs/mod.rs +++ b/kernel/src/filesystem/ramfs/mod.rs @@ -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::{ diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index 95e6ee2e..bdbbc3c9 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -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); } diff --git a/kernel/src/filesystem/vfs/mount.rs b/kernel/src/filesystem/vfs/mount.rs index f368d75c..136400a6 100644 --- a/kernel/src/filesystem/vfs/mount.rs +++ b/kernel/src/filesystem/vfs/mount.rs @@ -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 { - return self - .inner_inode - .write_at(offset, len, buf, data); + return self.inner_inode.write_at(offset, len, buf, data); } #[inline] diff --git a/kernel/src/io/device.rs b/kernel/src/io/device.rs index 581c308f..96a98764 100644 --- a/kernel/src/io/device.rs +++ b/kernel/src/io/device.rs @@ -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; + fn read_at( + &self, + lba_id_start: BlockId, + count: usize, + buf: &mut [u8], + ) -> Result; /// @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; + fn write_at( + &self, + lba_id_start: BlockId, + count: usize, + buf: &[u8], + ) -> Result; /// @brief: 同步磁盘信息,把所有的dirty数据写回硬盘 - 待实现 fn sync(&self) -> Result<(), SystemError>; diff --git a/kernel/src/ipc/signal.rs b/kernel/src/ipc/signal.rs index 192b8cef..8622b19d 100644 --- a/kernel/src/ipc/signal.rs +++ b/kernel/src/ipc/signal.rs @@ -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); } } @@ -724,8 +724,12 @@ fn setup_frame( // 设置cs和ds寄存器 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 Result { +fn setup_sigcontext( + context: &mut sigcontext, + mask: &sigset_t, + regs: &pt_regs, +) -> Result { 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的引用 diff --git a/kernel/src/ipc/signal_types.rs b/kernel/src/ipc/signal_types.rs index 3fee759b..406fafad 100644 --- a/kernel/src/ipc/signal_types.rs +++ b/kernel/src/ipc/signal_types.rs @@ -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, } diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 4c08bfc1..3c132138 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -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] diff --git a/kernel/src/libs/lockref.rs b/kernel/src/libs/lockref.rs index 87fe9d0c..5e023551 100644 --- a/kernel/src/libs/lockref.rs +++ b/kernel/src/libs/lockref.rs @@ -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 { 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); } } diff --git a/kernel/src/libs/mutex.rs b/kernel/src/libs/mutex.rs index 039ccd0e..e1c251f0 100644 --- a/kernel/src/libs/mutex.rs +++ b/kernel/src/libs/mutex.rs @@ -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; diff --git a/kernel/src/libs/rbtree.rs b/kernel/src/libs/rbtree.rs index b7271948..1d4dcbfe 100644 --- a/kernel/src/libs/rbtree.rs +++ b/kernel/src/libs/rbtree.rs @@ -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 NodePtr { unsafe { (*self.0).right = right } } - #[inline] fn parent(&self) -> NodePtr { 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 FromIterator<(K, V)> for RBTree { fn from_iter>(iter: T) -> RBTree { 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 IntoIterator for RBTree { type Item = (K, V); type IntoIter = IntoIter; @@ -1387,7 +1388,9 @@ impl RBTree { /// Return the value iter mut #[inline] pub fn values_mut(&mut self) -> ValuesMut { - 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(); @@ -1788,4 +1790,4 @@ mod tests { assert_eq!(a[&2], "two"); assert_eq!(a[&3], "three"); } -} \ No newline at end of file +} diff --git a/kernel/src/libs/rwlock.rs b/kernel/src/libs/rwlock.rs index b665a850..1ef85eaa 100644 --- a/kernel/src/libs/rwlock.rs +++ b/kernel/src/libs/rwlock.rs @@ -7,7 +7,7 @@ use core::{ sync::atomic::{AtomicU32, Ordering}, }; -use crate::{syscall::SystemError}; +use crate::syscall::SystemError; ///RwLock读写锁 diff --git a/kernel/src/libs/volatile.rs b/kernel/src/libs/volatile.rs index 2e55e7be..c66b3969 100644 --- a/kernel/src/libs/volatile.rs +++ b/kernel/src/libs/volatile.rs @@ -59,10 +59,10 @@ macro_rules! volatile_write_bit { /// queue_driver: Volatile, /// queue_device: Volatile, /// } -/// +/// /// 对CommonCfg里面的某个寄存器进行读写: /// volwrite!(self.common_cfg, queue_enable, 0); -/// +/// /// 这样做不仅使代码的可读性提高了,也避免了对只读寄存器进行写入的误操作 /// 只读寄存器 diff --git a/kernel/src/main.c b/kernel/src/main.c index 8a8c1097..581d8f09 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -147,6 +147,7 @@ void system_initialize() // ps2_mouse_init(); // ata_init(); pci_init(); + rs_pci_init(); io_mfence(); // test_slab(); diff --git a/kernel/src/mm/mmio_buddy.rs b/kernel/src/mm/mmio_buddy.rs index 0f144972..53ea362c 100644 --- a/kernel/src/mm/mmio_buddy.rs +++ b/kernel/src/mm/mmio_buddy.rs @@ -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, }; diff --git a/kernel/src/mm/mod.rs b/kernel/src/mm/mod.rs index 48732011..9abab484 100644 --- a/kernel/src/mm/mod.rs +++ b/kernel/src/mm/mod.rs @@ -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; @@ -22,4 +22,4 @@ unsafe impl Send for process_control_block {} unsafe impl Sync for process_control_block {} unsafe impl Send for mm_struct {} -unsafe impl Sync for mm_struct {} \ No newline at end of file +unsafe impl Sync for mm_struct {} diff --git a/kernel/src/process/fork.rs b/kernel/src/process/fork.rs index dc261561..80b40d9a 100644 --- a/kernel/src/process/fork.rs +++ b/kernel/src/process/fork.rs @@ -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] diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 0472963d..a147f9ed 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -1,3 +1,4 @@ + use num_traits::{FromPrimitive, ToPrimitive}; #[repr(i32)]