mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 02:46:47 +00:00
pci重构+pcie支持 (#235)
* pci重构+pcie支持 * pci重构测试完成 * 修正makefile的问题 * 小修改 * 修改函数名字
This commit is contained in:
parent
5c9a63df83
commit
78bf93f02f
27
kernel/src/arch/mod.rs
Normal file
27
kernel/src/arch/mod.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
pub mod x86_64;
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub use self::x86_64::pci::pci::X86_64PciArch as PciArch;
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub use self::x86_64::*; //公开x86_64架构下的函数,使外界接口统一
|
||||||
|
use crate::driver::pci::pci::{BusDeviceFunction, PciError, PciRoot, SegmentGroupNumber};
|
||||||
|
/// TraitPciArch Pci架构相关函数,任何架构都应独立实现trait里的函数
|
||||||
|
pub trait TraitPciArch {
|
||||||
|
/// @brief 读取寄存器值,x86_64架构通过读取两个特定io端口实现
|
||||||
|
/// @param bus_device_function 设备的唯一标识符
|
||||||
|
/// @param offset 寄存器偏移值
|
||||||
|
/// @return 读取到的值
|
||||||
|
fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32;
|
||||||
|
/// @brief 写入寄存器值,x86_64架构通过读取两个特定io端口实现
|
||||||
|
/// @param bus_device_function 设备的唯一标识符
|
||||||
|
/// @param offset 寄存器偏移值
|
||||||
|
/// @param data 要写入的值
|
||||||
|
fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32);
|
||||||
|
/// @brief PCI域地址到存储器域地址的转换,x86_64架构为一一对应
|
||||||
|
/// @param address PCI域地址
|
||||||
|
/// @return Result<usize, PciError> 转换结果或出错原因
|
||||||
|
fn address_pci_to_address_memory(address: usize) -> Result<usize, PciError>;
|
||||||
|
/// @brief 获取Segement的root地址,x86_64架构为acpi mcfg表中读取
|
||||||
|
/// @param segement 组id
|
||||||
|
/// @return Result<PciRoot, PciError> 转换结果或出错原因
|
||||||
|
fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError>;
|
||||||
|
}
|
@ -2,7 +2,7 @@ use crate::include::bindings::bindings::{process_control_block, switch_proc};
|
|||||||
|
|
||||||
use core::sync::atomic::compiler_fence;
|
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 切换进程的上下文(没有切换页表的动作)
|
/// @brief 切换进程的上下文(没有切换页表的动作)
|
||||||
///
|
///
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
pub mod asm;
|
pub mod asm;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
|
pub mod fpu;
|
||||||
pub mod interrupt;
|
pub mod interrupt;
|
||||||
pub mod mm;
|
pub mod mm;
|
||||||
|
pub mod pci;
|
||||||
pub mod sched;
|
pub mod sched;
|
||||||
pub mod fpu;
|
|
||||||
|
1
kernel/src/arch/x86_64/pci/mod.rs
Normal file
1
kernel/src/arch/x86_64/pci/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod pci;
|
70
kernel/src/arch/x86_64/pci/pci.rs
Normal file
70
kernel/src/arch/x86_64/pci/pci.rs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
use crate::arch::TraitPciArch;
|
||||||
|
use crate::driver::acpi::acpi::mcfg_find_segment;
|
||||||
|
use crate::driver::pci::pci::{
|
||||||
|
BusDeviceFunction, PciError, PciRoot, SegmentGroupNumber, PORT_PCI_CONFIG_ADDRESS,
|
||||||
|
PORT_PCI_CONFIG_DATA,
|
||||||
|
};
|
||||||
|
use crate::include::bindings::bindings::{
|
||||||
|
acpi_get_MCFG, acpi_iter_SDT, acpi_system_description_table_header_t, io_in32, io_out32,
|
||||||
|
};
|
||||||
|
|
||||||
|
use core::ffi::c_void;
|
||||||
|
use core::ptr::NonNull;
|
||||||
|
pub struct X86_64PciArch {}
|
||||||
|
impl TraitPciArch for X86_64PciArch {
|
||||||
|
fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 {
|
||||||
|
// 构造pci配置空间地址
|
||||||
|
let address = ((bus_device_function.bus as u32) << 16)
|
||||||
|
| ((bus_device_function.device as u32) << 11)
|
||||||
|
| ((bus_device_function.function as u32 & 7) << 8)
|
||||||
|
| (offset & 0xfc) as u32
|
||||||
|
| (0x80000000);
|
||||||
|
let ret = unsafe {
|
||||||
|
io_out32(PORT_PCI_CONFIG_ADDRESS, address);
|
||||||
|
let temp = io_in32(PORT_PCI_CONFIG_DATA);
|
||||||
|
temp
|
||||||
|
};
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) {
|
||||||
|
let address = ((bus_device_function.bus as u32) << 16)
|
||||||
|
| ((bus_device_function.device as u32) << 11)
|
||||||
|
| ((bus_device_function.function as u32 & 7) << 8)
|
||||||
|
| (offset & 0xfc) as u32
|
||||||
|
| (0x80000000);
|
||||||
|
unsafe {
|
||||||
|
io_out32(PORT_PCI_CONFIG_ADDRESS, address);
|
||||||
|
// 写入数据
|
||||||
|
io_out32(PORT_PCI_CONFIG_DATA, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn address_pci_to_address_memory(address: usize) -> Result<usize, PciError> {
|
||||||
|
Ok(address)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError> {
|
||||||
|
let mut data: usize = 0;
|
||||||
|
let data_point = &mut data;
|
||||||
|
unsafe {
|
||||||
|
acpi_iter_SDT(Some(acpi_get_MCFG), data_point as *mut usize as *mut c_void);
|
||||||
|
};
|
||||||
|
//kdebug!("{}",data);
|
||||||
|
//loop{}
|
||||||
|
let head = NonNull::new(data as *mut acpi_system_description_table_header_t).unwrap();
|
||||||
|
let outcome = unsafe { mcfg_find_segment(head).as_ref() };
|
||||||
|
for segmentgroupconfiguration in outcome {
|
||||||
|
if segmentgroupconfiguration.segement_group_number == segement {
|
||||||
|
return Ok(PciRoot {
|
||||||
|
physical_address_base: segmentgroupconfiguration.base_address,
|
||||||
|
mmio_base: None,
|
||||||
|
segement_group_number: segement,
|
||||||
|
bus_begin: segmentgroupconfiguration.bus_begin,
|
||||||
|
bus_end: segmentgroupconfiguration.bus_end,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Err(PciError::SegmentNotFound);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
CFLAGS += -I .
|
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:
|
||||||
@echo "$@"
|
@echo "$@"
|
||||||
|
@ -103,6 +103,22 @@ bool acpi_get_HPET(const struct acpi_system_description_table_header_t *_iter_da
|
|||||||
return true;
|
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模块
|
* @brief 初始化acpi模块
|
||||||
*
|
*
|
||||||
|
@ -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);
|
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模块
|
// 初始化acpi模块
|
||||||
void acpi_init();
|
void acpi_init();
|
27
kernel/src/driver/acpi/acpi.rs
Normal file
27
kernel/src/driver/acpi/acpi.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use crate::driver::pci::pci::SegmentGroupNumber;
|
||||||
|
use crate::include::bindings::bindings::acpi_system_description_table_header_t;
|
||||||
|
use core::ptr::{slice_from_raw_parts_mut, NonNull};
|
||||||
|
// MCFG表中的Segement配置部分,开始位置为44+16*n
|
||||||
|
#[repr(C, packed)]
|
||||||
|
pub struct Segement_Configuration_Space {
|
||||||
|
pub base_address: u64,
|
||||||
|
pub segement_group_number: SegmentGroupNumber,
|
||||||
|
pub bus_begin: u8,
|
||||||
|
pub bus_end: u8,
|
||||||
|
pub reverse: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief 获取Segement_Configuration_Space的数量并返回对应数量的Segement_Configuration_Space的切片指针
|
||||||
|
/// @param head acpi_system_description_table_header_t的指针
|
||||||
|
/// @return NonNull<[Segement_Configuration_Space]>
|
||||||
|
pub fn mcfg_find_segment(
|
||||||
|
head: NonNull<acpi_system_description_table_header_t>,
|
||||||
|
) -> NonNull<[Segement_Configuration_Space]> {
|
||||||
|
let table_length = unsafe { (*head.as_ptr()).Length };
|
||||||
|
let number_of_segments = ((table_length - 44) / 16) as u16;
|
||||||
|
NonNull::new(slice_from_raw_parts_mut(
|
||||||
|
(head.as_ptr() as usize + 44) as *mut _,
|
||||||
|
number_of_segments as usize,
|
||||||
|
))
|
||||||
|
.unwrap()
|
||||||
|
}
|
1
kernel/src/driver/acpi/mod.rs
Normal file
1
kernel/src/driver/acpi/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod acpi;
|
@ -1,16 +1,8 @@
|
|||||||
use alloc::{
|
use super::{driver::Driver, Device, DeviceState, IdTable};
|
||||||
collections::BTreeMap,
|
|
||||||
sync::Arc
|
|
||||||
};
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use core::fmt::Debug;
|
|
||||||
use crate::libs::spinlock::SpinLock;
|
use crate::libs::spinlock::SpinLock;
|
||||||
use super::{
|
use alloc::{collections::BTreeMap, sync::Arc};
|
||||||
driver::Driver,
|
use core::fmt::Debug;
|
||||||
DeviceState,
|
use lazy_static::lazy_static;
|
||||||
IdTable,
|
|
||||||
Device
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief: 总线状态
|
/// @brief: 总线状态
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
@ -3,9 +3,7 @@ use core::{any::Any, fmt::Debug};
|
|||||||
|
|
||||||
/// @brief: Driver error
|
/// @brief: Driver error
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
#[derive(PartialEq, Eq)]
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub enum DriverError {
|
pub enum DriverError {
|
||||||
ProbeError,
|
ProbeError,
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,7 @@ pub enum DeviceType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief: 设备标识符类型
|
/// @brief: 设备标识符类型
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)]
|
||||||
#[derive(Clone)]
|
|
||||||
#[derive(Hash)]
|
|
||||||
#[derive(PartialOrd, PartialEq)]
|
|
||||||
#[derive(Ord, Eq)]
|
|
||||||
pub struct IdTable(&'static str, u32);
|
pub struct IdTable(&'static str, u32);
|
||||||
|
|
||||||
/// @brief: 设备标识符操作方法集
|
/// @brief: 设备标识符操作方法集
|
||||||
@ -38,8 +34,7 @@ impl IdTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief: 设备当前状态
|
/// @brief: 设备当前状态
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub enum DeviceState {
|
pub enum DeviceState {
|
||||||
NotInitialized = 0,
|
NotInitialized = 0,
|
||||||
Initialized = 1,
|
Initialized = 1,
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
pub mod platform;
|
|
||||||
pub mod device;
|
pub mod device;
|
||||||
|
pub mod platform;
|
||||||
|
@ -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::{
|
use super::device::{
|
||||||
bus::{
|
bus::{Bus, BusDriver, BusState, BUS_MANAGER},
|
||||||
BusDriver,
|
|
||||||
BusState,
|
|
||||||
BUS_MANAGER,
|
|
||||||
Bus
|
|
||||||
},
|
|
||||||
driver::Driver,
|
driver::Driver,
|
||||||
IdTable,
|
Device, DeviceError, DeviceState, DeviceType, IdTable,
|
||||||
DeviceError,
|
|
||||||
DeviceState,
|
|
||||||
DeviceType, Device
|
|
||||||
};
|
};
|
||||||
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_device::PlatformDevice;
|
||||||
use platform_driver::PlatformDriver;
|
use platform_driver::PlatformDriver;
|
||||||
|
|
||||||
@ -108,7 +101,10 @@ impl PlatformBusDriver {
|
|||||||
/// @parameter driver: platform类型驱动,该驱动需要实现PlatformDriver trait
|
/// @parameter driver: platform类型驱动,该驱动需要实现PlatformDriver trait
|
||||||
/// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型
|
/// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn register_platform_driver(&mut self, driver: Arc<dyn PlatformDriver>) -> Result<(), DeviceError> {
|
fn register_platform_driver(
|
||||||
|
&mut self,
|
||||||
|
driver: Arc<dyn PlatformDriver>,
|
||||||
|
) -> Result<(), DeviceError> {
|
||||||
let id_table = driver.get_id_table();
|
let id_table = driver.get_id_table();
|
||||||
|
|
||||||
let mut drivers = self.drivers.write();
|
let mut drivers = self.drivers.write();
|
||||||
@ -135,7 +131,10 @@ impl PlatformBusDriver {
|
|||||||
/// @parameter driver: platform类型设备,该驱动需要实现PlatformDevice trait
|
/// @parameter driver: platform类型设备,该驱动需要实现PlatformDevice trait
|
||||||
/// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型
|
/// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn register_platform_device(&mut self, device: Arc<dyn PlatformDevice>) -> Result<(), DeviceError> {
|
fn register_platform_device(
|
||||||
|
&mut self,
|
||||||
|
device: Arc<dyn PlatformDevice>,
|
||||||
|
) -> Result<(), DeviceError> {
|
||||||
let id_table = device.get_id_table();
|
let id_table = device.get_id_table();
|
||||||
|
|
||||||
let mut devices = self.devices.write();
|
let mut devices = self.devices.write();
|
||||||
@ -166,7 +165,10 @@ impl PlatformBusDriver {
|
|||||||
let devices = self.devices.read();
|
let devices = self.devices.read();
|
||||||
|
|
||||||
for (_dev_id_table, device) in devices.iter() {
|
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() {
|
if !device.is_initialized() {
|
||||||
// 设备未初始化,调用驱动probe函数
|
// 设备未初始化,调用驱动probe函数
|
||||||
match driver.probe(device.clone()) {
|
match driver.probe(device.clone()) {
|
||||||
@ -194,7 +196,10 @@ impl PlatformBusDriver {
|
|||||||
fn device_match_driver(&self, device: Arc<dyn PlatformDevice>) -> Result<(), DeviceError> {
|
fn device_match_driver(&self, device: Arc<dyn PlatformDevice>) -> Result<(), DeviceError> {
|
||||||
let drivers = self.drivers.read();
|
let drivers = self.drivers.read();
|
||||||
for (_drv_id_table, driver) in &*drivers {
|
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()) {
|
match driver.probe(device.clone()) {
|
||||||
Ok(_driver) => {
|
Ok(_driver) => {
|
||||||
// 将设备状态置为已初始化
|
// 将设备状态置为已初始化
|
||||||
@ -228,8 +233,7 @@ impl BusDriver for PlatformBusDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief: platform总线
|
/// @brief: platform总线
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Platform {
|
pub struct Platform {
|
||||||
state: Arc<Mutex<BusState>>, // 总线状态
|
state: Arc<Mutex<BusState>>, // 总线状态
|
||||||
driver: Option<Arc<PlatformBusDriver>>, // 总线驱动
|
driver: Option<Arc<PlatformBusDriver>>, // 总线驱动
|
||||||
@ -332,16 +336,26 @@ lazy_static! {
|
|||||||
/// @return: None
|
/// @return: None
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn platform_bus_init() {
|
pub fn platform_bus_init() {
|
||||||
BUS_MANAGER.add_bus_driver(BUS_PLATFORM_DRIVER.get_id_table(), BUS_PLATFORM_DRIVER.clone());
|
BUS_MANAGER.add_bus_driver(
|
||||||
BUS_MANAGER.add_bus(BUS_PLATFORM_DEVICE.get_id_table(), BUS_PLATFORM_DEVICE.clone());
|
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);
|
BUS_PLATFORM_DEVICE.set_state(BusState::Initialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn c_platform_bus_init() {
|
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_driver(
|
||||||
BUS_MANAGER.add_bus(BUS_PLATFORM_DEVICE.get_id_table(), BUS_PLATFORM_DEVICE.clone());
|
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);
|
BUS_PLATFORM_DEVICE.set_state(BusState::Initialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
use alloc::sync::Arc;
|
|
||||||
use super::{
|
use super::{
|
||||||
super::device::{
|
super::device::{Device, DeviceState, DeviceType},
|
||||||
Device,
|
platform_driver::PlatformDriver,
|
||||||
DeviceType,
|
CompatibleTable,
|
||||||
DeviceState
|
|
||||||
},
|
|
||||||
CompatibleTable, platform_driver::PlatformDriver
|
|
||||||
};
|
};
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
/// @brief: 实现该trait的设备实例应挂载在platform总线上,
|
/// @brief: 实现该trait的设备实例应挂载在platform总线上,
|
||||||
/// 同时应该实现Device trait
|
/// 同时应该实现Device trait
|
||||||
@ -35,4 +32,3 @@ pub trait PlatformDevice: Device {
|
|||||||
/// @return: None
|
/// @return: None
|
||||||
fn set_driver(&self, driver: Option<Arc<dyn PlatformDriver>>);
|
fn set_driver(&self, driver: Option<Arc<dyn PlatformDriver>>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
use alloc::sync::Arc;
|
|
||||||
use super::{
|
use super::{
|
||||||
super::device::driver::{
|
super::device::driver::{Driver, DriverError},
|
||||||
Driver,
|
|
||||||
DriverError
|
|
||||||
},
|
|
||||||
platform_device::PlatformDevice,
|
platform_device::PlatformDevice,
|
||||||
CompatibleTable,
|
CompatibleTable,
|
||||||
};
|
};
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
/// @brief: 实现该trait的设备驱动实例应挂载在platform总线上,
|
/// @brief: 实现该trait的设备驱动实例应挂载在platform总线上,
|
||||||
/// 同时应该实现Driver trait
|
/// 同时应该实现Driver trait
|
||||||
|
@ -6,10 +6,7 @@ use crate::filesystem::vfs::{
|
|||||||
};
|
};
|
||||||
use crate::io::device::BlockDevice;
|
use crate::io::device::BlockDevice;
|
||||||
use crate::syscall::SystemError;
|
use crate::syscall::SystemError;
|
||||||
use crate::{
|
use crate::{libs::spinlock::SpinLock, time::TimeSpec};
|
||||||
libs::spinlock::SpinLock,
|
|
||||||
time::TimeSpec,
|
|
||||||
};
|
|
||||||
use alloc::{
|
use alloc::{
|
||||||
string::String,
|
string::String,
|
||||||
sync::{Arc, Weak},
|
sync::{Arc, Weak},
|
||||||
|
@ -177,7 +177,6 @@ pub fn get_disks_by_name(name: String) -> Result<Arc<LockedAhciDisk>, SystemErro
|
|||||||
}
|
}
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
return Err(SystemError::ENXIO);
|
return Err(SystemError::ENXIO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief: 通过 ctrl_num 和 port_num 获取 port
|
/// @brief: 通过 ctrl_num 和 port_num 获取 port
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
pub mod acpi;
|
||||||
|
pub mod base;
|
||||||
pub mod disk;
|
pub mod disk;
|
||||||
pub mod keyboard;
|
pub mod keyboard;
|
||||||
pub mod pci;
|
pub mod pci;
|
||||||
@ -6,4 +8,3 @@ pub mod tty;
|
|||||||
pub mod uart;
|
pub mod uart;
|
||||||
pub mod video;
|
pub mod video;
|
||||||
pub mod virtio;
|
pub mod virtio;
|
||||||
pub mod base;
|
|
||||||
|
@ -14,7 +14,7 @@ struct List *pci_device_structure_list = NULL;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void pci_init();
|
void pci_init();
|
||||||
|
void rs_pci_init();
|
||||||
// pci设备结构的通用标题字段
|
// pci设备结构的通用标题字段
|
||||||
struct pci_device_structure_header_t
|
struct pci_device_structure_header_t
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::interrupt::{cli, sti},
|
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 {
|
pub struct RtcTime {
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
use core::{ptr::null_mut, sync::atomic::{AtomicBool, Ordering}};
|
use core::{
|
||||||
|
ptr::null_mut,
|
||||||
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
exception::softirq::{SoftirqNumber, SoftirqVec, softirq_vectors},
|
exception::softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
|
||||||
include::bindings::bindings::video_refresh_framebuffer,
|
include::bindings::bindings::video_refresh_framebuffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct VideoRefreshFramebuffer {
|
pub struct VideoRefreshFramebuffer {
|
||||||
running: AtomicBool
|
running: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SoftirqVec for VideoRefreshFramebuffer {
|
impl SoftirqVec for VideoRefreshFramebuffer {
|
||||||
@ -28,7 +31,7 @@ impl SoftirqVec for VideoRefreshFramebuffer {
|
|||||||
impl VideoRefreshFramebuffer {
|
impl VideoRefreshFramebuffer {
|
||||||
pub fn new() -> VideoRefreshFramebuffer {
|
pub fn new() -> VideoRefreshFramebuffer {
|
||||||
VideoRefreshFramebuffer {
|
VideoRefreshFramebuffer {
|
||||||
running: AtomicBool::new(false)
|
running: AtomicBool::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
all: virtio.o
|
|
||||||
|
|
||||||
CFLAGS += -I .
|
|
||||||
|
|
||||||
virtio.o: virtio.c
|
|
||||||
$(CC) $(CFLAGS) -c virtio.c -o virtio.o
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
//! PCI transport for VirtIO.
|
//! PCI transport for VirtIO.
|
||||||
|
use crate::arch::{PciArch, TraitPciArch};
|
||||||
use crate::driver::pci::pci::{
|
use crate::driver::pci::pci::{
|
||||||
capabilities_offset, pci_bar_init, pci_enable_master, CapabilityIterator, DeviceFunction,
|
BusDeviceFunction, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
|
||||||
PciDeviceBar, PciError, PCI_CAP_ID_VNDR,
|
PciStandardDeviceBar, PCI_CAP_ID_VNDR,
|
||||||
};
|
};
|
||||||
use crate::include::bindings::bindings::pci_read_config;
|
|
||||||
|
|
||||||
use crate::libs::volatile::{
|
use crate::libs::volatile::{
|
||||||
volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
|
volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
|
||||||
@ -77,7 +77,7 @@ fn device_type(pci_device_id: u16) -> DeviceType {
|
|||||||
pub struct PciTransport {
|
pub struct PciTransport {
|
||||||
device_type: DeviceType,
|
device_type: DeviceType,
|
||||||
/// The bus, device and function identifier for the VirtIO device.
|
/// The bus, device and function identifier for the VirtIO device.
|
||||||
device_function: DeviceFunction,
|
bus_device_function: BusDeviceFunction,
|
||||||
/// The common configuration structure within some BAR.
|
/// The common configuration structure within some BAR.
|
||||||
common_cfg: NonNull<CommonCfg>,
|
common_cfg: NonNull<CommonCfg>,
|
||||||
/// The start of the queue notification region within some BAR.
|
/// 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
|
/// Construct a new PCI VirtIO device driver for the given device function on the given PCI
|
||||||
/// root controller.
|
/// root controller.
|
||||||
///
|
///
|
||||||
/// The PCI device must already have had its BARs allocated.
|
///
|
||||||
pub fn new<H: Hal>(device_function: DeviceFunction) -> Result<Self, VirtioPciError> {
|
pub fn new<H: Hal>(
|
||||||
let device_vendor = unsafe {
|
device: &mut PciDeviceStructureGeneralDevice,
|
||||||
let bar_temp = pci_read_config(
|
) -> Result<Self, VirtioPciError> {
|
||||||
device_function.bus,
|
let header = &device.common_header;
|
||||||
device_function.device,
|
let bus_device_function = header.bus_device_function;
|
||||||
device_function.function,
|
if header.vendor_id != VIRTIO_VENDOR_ID {
|
||||||
0,
|
return Err(VirtioPciError::InvalidVendorId(header.vendor_id));
|
||||||
);
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
let device_type = device_type(device_id);
|
let device_type = device_type(header.device_id);
|
||||||
// Find the PCI capabilities we need.
|
// Find the PCI capabilities we need.
|
||||||
let mut common_cfg = None;
|
let mut common_cfg = None;
|
||||||
let mut notify_cfg = None;
|
let mut notify_cfg = None;
|
||||||
let mut notify_off_multiplier = 0;
|
let mut notify_off_multiplier = 0;
|
||||||
let mut isr_cfg = None;
|
let mut isr_cfg = None;
|
||||||
let mut device_cfg = None;
|
let mut device_cfg = None;
|
||||||
|
device.bar_init().unwrap()?;
|
||||||
|
device.enable_master();
|
||||||
//device_capability为迭代器,遍历其相当于遍历所有的cap空间
|
//device_capability为迭代器,遍历其相当于遍历所有的cap空间
|
||||||
let device_capability = CapabilityIterator {
|
for capability in device.capabilities().unwrap() {
|
||||||
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 {
|
|
||||||
if capability.id != PCI_CAP_ID_VNDR {
|
if capability.id != PCI_CAP_ID_VNDR {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -134,33 +122,16 @@ impl PciTransport {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let struct_info = VirtioCapabilityInfo {
|
let struct_info = VirtioCapabilityInfo {
|
||||||
bar: unsafe {
|
bar: PciArch::read_config(&bus_device_function, capability.offset + CAP_BAR_OFFSET)
|
||||||
let temp = pci_read_config(
|
as u8,
|
||||||
device_function.bus,
|
offset: PciArch::read_config(
|
||||||
device_function.device,
|
&bus_device_function,
|
||||||
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,
|
capability.offset + CAP_BAR_OFFSET_OFFSET,
|
||||||
);
|
),
|
||||||
temp
|
length: PciArch::read_config(
|
||||||
},
|
&bus_device_function,
|
||||||
length: unsafe {
|
|
||||||
let temp = pci_read_config(
|
|
||||||
device_function.bus,
|
|
||||||
device_function.device,
|
|
||||||
device_function.function,
|
|
||||||
capability.offset + CAP_LENGTH_OFFSET,
|
capability.offset + CAP_LENGTH_OFFSET,
|
||||||
);
|
),
|
||||||
temp
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match cfg_type {
|
match cfg_type {
|
||||||
@ -169,15 +140,10 @@ impl PciTransport {
|
|||||||
}
|
}
|
||||||
VIRTIO_PCI_CAP_NOTIFY_CFG if cap_len >= 20 && notify_cfg.is_none() => {
|
VIRTIO_PCI_CAP_NOTIFY_CFG if cap_len >= 20 && notify_cfg.is_none() => {
|
||||||
notify_cfg = Some(struct_info);
|
notify_cfg = Some(struct_info);
|
||||||
notify_off_multiplier = unsafe {
|
notify_off_multiplier = PciArch::read_config(
|
||||||
let temp = pci_read_config(
|
&bus_device_function,
|
||||||
device_function.bus,
|
|
||||||
device_function.device,
|
|
||||||
device_function.function,
|
|
||||||
capability.offset + CAP_NOTIFY_OFF_MULTIPLIER_OFFSET,
|
capability.offset + CAP_NOTIFY_OFF_MULTIPLIER_OFFSET,
|
||||||
);
|
);
|
||||||
temp
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
VIRTIO_PCI_CAP_ISR_CFG if isr_cfg.is_none() => {
|
VIRTIO_PCI_CAP_ISR_CFG if isr_cfg.is_none() => {
|
||||||
isr_cfg = Some(struct_info);
|
isr_cfg = Some(struct_info);
|
||||||
@ -190,7 +156,7 @@ impl PciTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let common_cfg = get_bar_region::<_>(
|
let common_cfg = get_bar_region::<_>(
|
||||||
&device_bar,
|
&device.standard_device_bar,
|
||||||
&common_cfg.ok_or(VirtioPciError::MissingCommonConfig)?,
|
&common_cfg.ok_or(VirtioPciError::MissingCommonConfig)?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -201,19 +167,22 @@ impl PciTransport {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
//kdebug!("notify.offset={},notify.length={}",notify_cfg.offset,notify_cfg.length);
|
//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::<_>(
|
let isr_status = get_bar_region::<_>(
|
||||||
&device_bar,
|
&device.standard_device_bar,
|
||||||
&isr_cfg.ok_or(VirtioPciError::MissingIsrConfig)?,
|
&isr_cfg.ok_or(VirtioPciError::MissingIsrConfig)?,
|
||||||
)?;
|
)?;
|
||||||
let config_space = if let Some(device_cfg) = device_cfg {
|
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 {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
device_type,
|
device_type,
|
||||||
device_function,
|
bus_device_function,
|
||||||
common_cfg,
|
common_cfg,
|
||||||
notify_region,
|
notify_region,
|
||||||
notify_off_multiplier,
|
notify_off_multiplier,
|
||||||
@ -487,7 +456,7 @@ impl From<PciError> for VirtioPciError {
|
|||||||
///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息
|
///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息
|
||||||
///@return Result<NonNull<T>, VirtioPciError> 成功则返回对应类型的指针,失败则返回Error
|
///@return Result<NonNull<T>, VirtioPciError> 成功则返回对应类型的指针,失败则返回Error
|
||||||
fn get_bar_region<T>(
|
fn get_bar_region<T>(
|
||||||
device_bar: &PciDeviceBar,
|
device_bar: &PciStandardDeviceBar,
|
||||||
struct_info: &VirtioCapabilityInfo,
|
struct_info: &VirtioCapabilityInfo,
|
||||||
) -> Result<NonNull<T>, VirtioPciError> {
|
) -> Result<NonNull<T>, VirtioPciError> {
|
||||||
let bar_info = device_bar.get_bar(struct_info.bar)?;
|
let bar_info = device_bar.get_bar(struct_info.bar)?;
|
||||||
@ -521,7 +490,7 @@ fn get_bar_region<T>(
|
|||||||
///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息切片的指针
|
///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息切片的指针
|
||||||
///@return Result<NonNull<[T]>, VirtioPciError> 成功则返回对应类型的指针切片,失败则返回Error
|
///@return Result<NonNull<[T]>, VirtioPciError> 成功则返回对应类型的指针切片,失败则返回Error
|
||||||
fn get_bar_region_slice<T>(
|
fn get_bar_region_slice<T>(
|
||||||
device_bar: &PciDeviceBar,
|
device_bar: &PciStandardDeviceBar,
|
||||||
struct_info: &VirtioCapabilityInfo,
|
struct_info: &VirtioCapabilityInfo,
|
||||||
) -> Result<NonNull<[T]>, VirtioPciError> {
|
) -> Result<NonNull<[T]>, VirtioPciError> {
|
||||||
let ptr = get_bar_region::<T>(device_bar, struct_info)?;
|
let ptr = get_bar_region::<T>(device_bar, struct_info)?;
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
#include "virtio.h"
|
|
||||||
#include <common/kprint.h>
|
|
||||||
#include <common/errno.h>
|
|
||||||
#include <driver/pci/pci.h>
|
|
||||||
|
|
||||||
#define MAX_NET_NUM 8 // pci总线上的net设备的最大数量
|
|
||||||
|
|
||||||
// 在pci总线上寻找到net设备控制器的header
|
|
||||||
static struct pci_device_structure_header_t *net_pdevs[MAX_NET_NUM];
|
|
||||||
static int net_pdevs_count = 0;
|
|
||||||
static struct pci_device_structure_header_t *virtio_net_pdev;
|
|
||||||
static int virtio_net_pdev_count = 0;
|
|
||||||
static uint8_t NETWORK_CLASS = 0x2;
|
|
||||||
static uint8_t ETHERNET_SUBCLASS = 0x0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取virtio-net MMIO映射的虚拟地址
|
|
||||||
* @param virt_addr 外部传入的虚拟地址指针
|
|
||||||
* @return 获取成功,返回0,失败,返回错误码
|
|
||||||
*/
|
|
||||||
uint8_t get_virtio_net_device(uint8_t * bus, uint8_t *device,uint8_t * function)
|
|
||||||
{
|
|
||||||
// 获取所有net-pci设备的列表
|
|
||||||
pci_get_device_structure(NETWORK_CLASS, ETHERNET_SUBCLASS, net_pdevs, &net_pdevs_count);
|
|
||||||
//检测其中的virt-io-net设备
|
|
||||||
for(int i = 0; i < net_pdevs_count;i++) {
|
|
||||||
struct pci_device_structure_general_device_t *dev = net_pdevs[i];
|
|
||||||
if(net_pdevs[i]->Vendor_ID==0x1AF4 && net_pdevs[i]->Device_ID>=0x1000 && net_pdevs[i]->Device_ID<=0x103F && dev->Subsystem_ID==1)
|
|
||||||
{
|
|
||||||
virtio_net_pdev=net_pdevs[i];
|
|
||||||
virtio_net_pdev_count++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (virtio_net_pdev_count == 0) {
|
|
||||||
kwarn("There is no virtio-net device in this computer!");
|
|
||||||
return NOT_FOUND_DEVICE;
|
|
||||||
}
|
|
||||||
if (virtio_net_pdev->Command==0) {
|
|
||||||
kwarn("The virtio-net device isn't support mmio!");
|
|
||||||
return NOT_SUPPORTE_MMIO;
|
|
||||||
}
|
|
||||||
*bus=virtio_net_pdev->bus;
|
|
||||||
*device=virtio_net_pdev->device;
|
|
||||||
*function=virtio_net_pdev->func;
|
|
||||||
}
|
|
@ -1,12 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <common/glib.h>
|
#include <common/glib.h>
|
||||||
|
|
||||||
#define GET_VIRTADDRESS_SUCCESS 0
|
|
||||||
#define NOT_FOUND_DEVICE 1
|
|
||||||
#define NOT_SUPPORTE_MMIO 2
|
|
||||||
#define GET_VIRTADDRESS_FAILURE 3
|
|
||||||
|
|
||||||
// 获取virtio-net 设备
|
|
||||||
uint8_t get_virtio_net_device(uint8_t * bus, uint8_t *device,uint8_t * function);
|
|
||||||
//寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备后续也可添加)
|
//寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备后续也可添加)
|
||||||
void c_virtio_probe();
|
void c_virtio_probe();
|
||||||
|
@ -1,53 +1,42 @@
|
|||||||
use super::transport_pci::PciTransport;
|
use super::transport_pci::PciTransport;
|
||||||
use super::virtio_impl::HalImpl;
|
use super::virtio_impl::HalImpl;
|
||||||
use crate::driver::pci::pci::DeviceFunction;
|
use crate::driver::pci::pci::PciDeviceStructureGeneralDevice;
|
||||||
use crate::include::bindings::bindings::get_virtio_net_device;
|
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 crate::{kdebug, kerror, kwarn};
|
||||||
use alloc::{boxed::Box, collections::LinkedList};
|
use alloc::{boxed::Box, collections::LinkedList};
|
||||||
use virtio_drivers::device::net::VirtIONet;
|
use virtio_drivers::device::net::VirtIONet;
|
||||||
use virtio_drivers::transport::{DeviceType, Transport};
|
use virtio_drivers::transport::{DeviceType, Transport};
|
||||||
|
const NETWORK_CLASS: u8 = 0x2;
|
||||||
|
const ETHERNET_SUBCLASS: u8 = 0x0;
|
||||||
|
|
||||||
//Virtio设备寻找过程中出现的问题
|
//Virtio设备寻找过程中出现的问题
|
||||||
enum VirtioError {
|
enum VirtioError {
|
||||||
VirtioNetNotFound,
|
VirtioNetNotFound,
|
||||||
|
NetDeviceNotFound,
|
||||||
}
|
}
|
||||||
|
|
||||||
///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)(for c)
|
///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)(for c)
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn c_virtio_probe() {
|
pub extern "C" fn c_virtio_probe() {
|
||||||
if let Ok(virtio_list) = virtio_device_search() {
|
virtio_probe();
|
||||||
for device_function in virtio_list {
|
|
||||||
match PciTransport::new::<HalImpl>(*device_function) {
|
|
||||||
Ok(mut transport) => {
|
|
||||||
kdebug!(
|
|
||||||
"Detected virtio PCI device with device type {:?}, features {:#018x}",
|
|
||||||
transport.device_type(),
|
|
||||||
transport.read_device_features(),
|
|
||||||
);
|
|
||||||
virtio_device(transport);
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
kerror!("Pci transport create failed because of error: {}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
kerror!("Error occured when finding virtio device!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)
|
///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)
|
||||||
fn virtio_probe() {
|
pub fn virtio_probe() {
|
||||||
if let Ok(virtio_list) = virtio_device_search() {
|
let mut list = PCI_DEVICE_LINKEDLIST.write();
|
||||||
for device_function in virtio_list {
|
if let Ok(virtio_list) = virtio_device_search(&mut list) {
|
||||||
match PciTransport::new::<HalImpl>(*device_function) {
|
for virtio_device in virtio_list {
|
||||||
|
match PciTransport::new::<HalImpl>(virtio_device) {
|
||||||
Ok(mut transport) => {
|
Ok(mut transport) => {
|
||||||
kdebug!(
|
kdebug!(
|
||||||
"Detected virtio PCI device with device type {:?}, features {:#018x}",
|
"Detected virtio PCI device with device type {:?}, features {:#018x}",
|
||||||
transport.device_type(),
|
transport.device_type(),
|
||||||
transport.read_device_features(),
|
transport.read_device_features(),
|
||||||
);
|
);
|
||||||
virtio_device(transport);
|
virtio_device_init(transport);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
kerror!("Pci transport create failed because of error: {}", err);
|
kerror!("Pci transport create failed because of error: {}", err);
|
||||||
@ -60,7 +49,7 @@ fn virtio_probe() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///@brief 为virtio设备寻找对应的驱动进行初始化
|
///@brief 为virtio设备寻找对应的驱动进行初始化
|
||||||
fn virtio_device(transport: impl Transport) {
|
fn virtio_device_init(transport: impl Transport) {
|
||||||
match transport.device_type() {
|
match transport.device_type() {
|
||||||
DeviceType::Block => {
|
DeviceType::Block => {
|
||||||
kwarn!("Not support virtio_block device for now");
|
kwarn!("Not support virtio_block device for now");
|
||||||
@ -131,29 +120,38 @@ fn virtio_net<T: Transport>(transport: T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 寻找所有的virtio设备
|
/// @brief 寻找所有的virtio设备
|
||||||
/// @return Result<LinkedList<Box<DeviceFunction>>,VirtioError> 成功则返回包含所有virtio设备的链表,失败则返回err
|
/// @param list 链表的写锁
|
||||||
|
/// @return Result<LinkedList<&'a mut Pci_Device_Structure_General_Device>, VirtioError> 成功则返回包含所有virtio设备结构体的可变引用的链表,失败则返回err
|
||||||
/// 该函数主要是为其他virtio设备预留支持
|
/// 该函数主要是为其他virtio设备预留支持
|
||||||
fn virtio_device_search() -> Result<LinkedList<Box<DeviceFunction>>, VirtioError> {
|
fn virtio_device_search<'a>(
|
||||||
let mut virtio_list: LinkedList<Box<DeviceFunction>> = LinkedList::new();
|
list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
|
||||||
let (bus, device, function) = unsafe {
|
) -> Result<LinkedList<&'a mut PciDeviceStructureGeneralDevice>, VirtioError> {
|
||||||
let mut bus: u8 = 0;
|
let mut virtio_list: LinkedList<&mut PciDeviceStructureGeneralDevice> = LinkedList::new();
|
||||||
let mut device: u8 = 0;
|
let virtio_net_device = get_virtio_net_device(list)?;
|
||||||
let mut function: u8 = 0;
|
virtio_list.push_back(virtio_net_device);
|
||||||
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));
|
|
||||||
Ok(virtio_list)
|
Ok(virtio_list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief 寻找virtio-net设备
|
||||||
|
/// @param list 链表的写锁
|
||||||
|
/// @return Result<&'a mut Pci_Device_Structure_General_Device, VirtioError> 成功则返回virtio设备结构体的可变引用,失败则返回err
|
||||||
|
fn get_virtio_net_device<'a>(
|
||||||
|
list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
|
||||||
|
) -> Result<&'a mut PciDeviceStructureGeneralDevice, VirtioError> {
|
||||||
|
let result = get_pci_device_structure_mut(list, NETWORK_CLASS, ETHERNET_SUBCLASS);
|
||||||
|
if result.is_empty() {
|
||||||
|
return Err(VirtioError::NetDeviceNotFound);
|
||||||
|
}
|
||||||
|
for device in result {
|
||||||
|
let standard_device = device.as_standard_device_mut().unwrap();
|
||||||
|
let header = &standard_device.common_header;
|
||||||
|
if header.vendor_id == 0x1AF4
|
||||||
|
&& header.device_id >= 0x1000
|
||||||
|
&& header.device_id <= 0x103F
|
||||||
|
&& standard_device.subsystem_id == 1
|
||||||
|
{
|
||||||
|
return Ok(standard_device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(VirtioError::VirtioNetNotFound)
|
||||||
|
}
|
||||||
|
@ -3,7 +3,6 @@ use crate::include::bindings::bindings::{
|
|||||||
alloc_pages, free_pages, memory_management_struct, Page, PAGE_2M_SHIFT, PAGE_2M_SIZE,
|
alloc_pages, free_pages, memory_management_struct, Page, PAGE_2M_SHIFT, PAGE_2M_SIZE,
|
||||||
PAGE_OFFSET, PAGE_SHARED, ZONE_NORMAL,
|
PAGE_OFFSET, PAGE_SHARED, ZONE_NORMAL,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::mm::virt_2_phys;
|
use crate::mm::virt_2_phys;
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
|
@ -3,11 +3,7 @@ use crate::filesystem::vfs::make_rawdev;
|
|||||||
use crate::filesystem::vfs::{
|
use crate::filesystem::vfs::{
|
||||||
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
|
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{libs::spinlock::SpinLock, syscall::SystemError, time::TimeSpec};
|
||||||
syscall::SystemError,
|
|
||||||
libs::spinlock::SpinLock,
|
|
||||||
time::TimeSpec,
|
|
||||||
};
|
|
||||||
use alloc::{
|
use alloc::{
|
||||||
string::String,
|
string::String,
|
||||||
sync::{Arc, Weak},
|
sync::{Arc, Weak},
|
||||||
|
@ -3,11 +3,7 @@ use crate::filesystem::vfs::make_rawdev;
|
|||||||
use crate::filesystem::vfs::{
|
use crate::filesystem::vfs::{
|
||||||
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
|
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{libs::spinlock::SpinLock, syscall::SystemError, time::TimeSpec};
|
||||||
syscall::SystemError,
|
|
||||||
libs::spinlock::SpinLock,
|
|
||||||
time::TimeSpec,
|
|
||||||
};
|
|
||||||
use alloc::{
|
use alloc::{
|
||||||
string::String,
|
string::String,
|
||||||
sync::{Arc, Weak},
|
sync::{Arc, Weak},
|
||||||
|
@ -4,7 +4,8 @@ use alloc::{sync::Arc, vec::Vec};
|
|||||||
use crate::{
|
use crate::{
|
||||||
io::{device::LBA_SIZE, disk_info::Partition, SeekFrom},
|
io::{device::LBA_SIZE, disk_info::Partition, SeekFrom},
|
||||||
kerror,
|
kerror,
|
||||||
libs::vec_cursor::VecCursor, syscall::SystemError,
|
libs::vec_cursor::VecCursor,
|
||||||
|
syscall::SystemError,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::fs::{Cluster, FATFileSystem};
|
use super::fs::{Cluster, FATFileSystem};
|
||||||
|
@ -79,7 +79,12 @@ impl FATFile {
|
|||||||
///
|
///
|
||||||
/// @return Ok(usize) 成功读取到的字节数
|
/// @return Ok(usize) 成功读取到的字节数
|
||||||
/// @return Err(SystemError) 读取时出现错误,返回错误码
|
/// @return Err(SystemError) 读取时出现错误,返回错误码
|
||||||
pub fn read(&self, fs: &Arc<FATFileSystem>, buf: &mut [u8], offset: u64) -> Result<usize, SystemError> {
|
pub fn read(
|
||||||
|
&self,
|
||||||
|
fs: &Arc<FATFileSystem>,
|
||||||
|
buf: &mut [u8],
|
||||||
|
offset: u64,
|
||||||
|
) -> Result<usize, SystemError> {
|
||||||
if offset >= self.size() {
|
if offset >= self.size() {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
@ -223,7 +228,12 @@ impl FATFile {
|
|||||||
///
|
///
|
||||||
/// @return Ok(()) 经过操作后,offset后面具有长度至少为len的空闲空间
|
/// @return Ok(()) 经过操作后,offset后面具有长度至少为len的空闲空间
|
||||||
/// @return Err(SystemError) 处理过程中出现了异常。
|
/// @return Err(SystemError) 处理过程中出现了异常。
|
||||||
fn ensure_len(&mut self, fs: &Arc<FATFileSystem>, offset: u64, len: u64) -> Result<(), SystemError> {
|
fn ensure_len(
|
||||||
|
&mut self,
|
||||||
|
fs: &Arc<FATFileSystem>,
|
||||||
|
offset: u64,
|
||||||
|
len: u64,
|
||||||
|
) -> Result<(), SystemError> {
|
||||||
// 文件内本身就还有空余的空间
|
// 文件内本身就还有空余的空间
|
||||||
if offset + len <= self.size() {
|
if offset + len <= self.size() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -545,7 +555,6 @@ impl FATDir {
|
|||||||
} else {
|
} else {
|
||||||
return Err(err_val);
|
return Err(err_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match r.unwrap() {
|
match r.unwrap() {
|
||||||
@ -822,7 +831,11 @@ impl FATDir {
|
|||||||
///
|
///
|
||||||
/// @return Ok(FATDirEntry) 目标目录项
|
/// @return Ok(FATDirEntry) 目标目录项
|
||||||
/// @return Err(SystemError) 底层传上来的错误码
|
/// @return Err(SystemError) 底层传上来的错误码
|
||||||
pub fn get_dir_entry(&self, fs: Arc<FATFileSystem>, name: &str) -> Result<FATDirEntry, SystemError> {
|
pub fn get_dir_entry(
|
||||||
|
&self,
|
||||||
|
fs: Arc<FATFileSystem>,
|
||||||
|
name: &str,
|
||||||
|
) -> Result<FATDirEntry, SystemError> {
|
||||||
if name == "." || name == "/" {
|
if name == "." || name == "/" {
|
||||||
return Ok(FATDirEntry::Dir(self.clone()));
|
return Ok(FATDirEntry::Dir(self.clone()));
|
||||||
}
|
}
|
||||||
@ -1271,7 +1284,11 @@ impl ShortDirEntry {
|
|||||||
///
|
///
|
||||||
/// @return Ok(())
|
/// @return Ok(())
|
||||||
/// @return Err(SystemError) 错误码
|
/// @return Err(SystemError) 错误码
|
||||||
pub fn flush(&self, fs: &Arc<FATFileSystem>, disk_bytes_offset: u64) -> Result<(), SystemError> {
|
pub fn flush(
|
||||||
|
&self,
|
||||||
|
fs: &Arc<FATFileSystem>,
|
||||||
|
disk_bytes_offset: u64,
|
||||||
|
) -> Result<(), SystemError> {
|
||||||
// 从磁盘读取数据
|
// 从磁盘读取数据
|
||||||
let blk_offset = fs.get_in_block_offset(disk_bytes_offset);
|
let blk_offset = fs.get_in_block_offset(disk_bytes_offset);
|
||||||
let lba = fs.get_lba_from_offset(
|
let lba = fs.get_lba_from_offset(
|
||||||
|
@ -20,8 +20,8 @@ use crate::{
|
|||||||
spinlock::{SpinLock, SpinLockGuard},
|
spinlock::{SpinLock, SpinLockGuard},
|
||||||
vec_cursor::VecCursor,
|
vec_cursor::VecCursor,
|
||||||
},
|
},
|
||||||
time::TimeSpec,
|
|
||||||
syscall::SystemError,
|
syscall::SystemError,
|
||||||
|
time::TimeSpec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -1569,7 +1569,8 @@ impl IndexNode for LockedFATInode {
|
|||||||
dir.check_existence(name, Some(true), guard.fs.upgrade().unwrap())?;
|
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() {
|
if r.is_ok() {
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
|
@ -14,16 +14,16 @@ use crate::{
|
|||||||
core::{generate_inode_id, ROOT_INODE},
|
core::{generate_inode_id, ROOT_INODE},
|
||||||
FileType,
|
FileType,
|
||||||
},
|
},
|
||||||
include::bindings::bindings::{
|
include::bindings::bindings::{pid_t, process_find_pcb_by_pid},
|
||||||
pid_t, process_find_pcb_by_pid,
|
|
||||||
},
|
|
||||||
kerror,
|
kerror,
|
||||||
libs::spinlock::{SpinLock, SpinLockGuard},
|
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||||
time::TimeSpec, syscall::SystemError,
|
syscall::SystemError,
|
||||||
|
time::TimeSpec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::vfs::{
|
use super::vfs::{
|
||||||
file::{FilePrivateData, FileMode}, FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
|
file::{FileMode, FilePrivateData},
|
||||||
|
FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief 进程文件类型
|
/// @brief 进程文件类型
|
||||||
|
@ -10,7 +10,8 @@ use alloc::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
filesystem::vfs::{core::generate_inode_id, FileType},
|
filesystem::vfs::{core::generate_inode_id, FileType},
|
||||||
libs::spinlock::{SpinLock, SpinLockGuard},
|
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||||
time::TimeSpec, syscall::SystemError,
|
syscall::SystemError,
|
||||||
|
time::TimeSpec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::vfs::{
|
use super::vfs::{
|
||||||
|
@ -10,10 +10,7 @@ use ::core::{any::Any, fmt::Debug};
|
|||||||
|
|
||||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{syscall::SystemError, time::TimeSpec};
|
||||||
time::TimeSpec,
|
|
||||||
syscall::SystemError,
|
|
||||||
};
|
|
||||||
|
|
||||||
use self::{core::generate_inode_id, file::FileMode};
|
use self::{core::generate_inode_id, file::FileMode};
|
||||||
pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
|
pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
|
||||||
|
@ -5,11 +5,9 @@ use alloc::{
|
|||||||
sync::{Arc, Weak},
|
sync::{Arc, Weak},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{libs::spinlock::SpinLock, syscall::SystemError};
|
||||||
libs::spinlock::SpinLock, syscall::SystemError,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{FilePrivateData, FileSystem, FileType, IndexNode, InodeId, file::FileMode};
|
use super::{file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode, InodeId};
|
||||||
|
|
||||||
/// @brief 挂载文件系统
|
/// @brief 挂载文件系统
|
||||||
/// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
|
/// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
|
||||||
@ -166,9 +164,7 @@ impl IndexNode for MountFSInode {
|
|||||||
buf: &[u8],
|
buf: &[u8],
|
||||||
data: &mut FilePrivateData,
|
data: &mut FilePrivateData,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
return self
|
return self.inner_inode.write_at(offset, len, buf, data);
|
||||||
.inner_inode
|
|
||||||
.write_at(offset, len, buf, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/// 引入Module
|
/// 引入Module
|
||||||
use crate::{syscall::SystemError};
|
use crate::syscall::SystemError;
|
||||||
use alloc::{sync::Arc, vec::Vec};
|
use alloc::{sync::Arc, vec::Vec};
|
||||||
use core::{any::Any, fmt::Debug};
|
use core::{any::Any, fmt::Debug};
|
||||||
|
|
||||||
@ -45,7 +45,6 @@ pub trait Device: Any + Send + Sync + Debug {
|
|||||||
fn sync(&self) -> Result<(), SystemError>;
|
fn sync(&self) -> Result<(), SystemError>;
|
||||||
|
|
||||||
// TODO: 待实现 open, close
|
// TODO: 待实现 open, close
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 块设备应该实现的操作
|
/// @brief 块设备应该实现的操作
|
||||||
@ -58,7 +57,12 @@ pub trait BlockDevice: Any + Send + Sync + Debug {
|
|||||||
/// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
|
/// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
|
||||||
/// 否则返回Err(错误码),其中错误码为负数;
|
/// 否则返回Err(错误码),其中错误码为负数;
|
||||||
/// 如果操作异常,但是并没有检查出什么错误,将返回Err(已操作的长度)
|
/// 如果操作异常,但是并没有检查出什么错误,将返回Err(已操作的长度)
|
||||||
fn read_at(&self, lba_id_start: BlockId, count: usize, buf: &mut [u8]) -> Result<usize, SystemError>;
|
fn read_at(
|
||||||
|
&self,
|
||||||
|
lba_id_start: BlockId,
|
||||||
|
count: usize,
|
||||||
|
buf: &mut [u8],
|
||||||
|
) -> Result<usize, SystemError>;
|
||||||
|
|
||||||
/// @brief: 在块设备中,从第lba_id_start个块开始,把buf中的count个块数据,存放到设备中
|
/// @brief: 在块设备中,从第lba_id_start个块开始,把buf中的count个块数据,存放到设备中
|
||||||
/// @parameter lba_id_start: 起始块
|
/// @parameter lba_id_start: 起始块
|
||||||
@ -67,7 +71,12 @@ pub trait BlockDevice: Any + Send + Sync + Debug {
|
|||||||
/// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
|
/// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
|
||||||
/// 否则返回Err(错误码),其中错误码为负数;
|
/// 否则返回Err(错误码),其中错误码为负数;
|
||||||
/// 如果操作异常,但是并没有检查出什么错误,将返回Err(已操作的长度)
|
/// 如果操作异常,但是并没有检查出什么错误,将返回Err(已操作的长度)
|
||||||
fn write_at(&self, lba_id_start: BlockId, count: usize, buf: &[u8]) -> Result<usize, SystemError>;
|
fn write_at(
|
||||||
|
&self,
|
||||||
|
lba_id_start: BlockId,
|
||||||
|
count: usize,
|
||||||
|
buf: &[u8],
|
||||||
|
) -> Result<usize, SystemError>;
|
||||||
|
|
||||||
/// @brief: 同步磁盘信息,把所有的dirty数据写回硬盘 - 待实现
|
/// @brief: 同步磁盘信息,把所有的dirty数据写回硬盘 - 待实现
|
||||||
fn sync(&self) -> Result<(), SystemError>;
|
fn sync(&self) -> Result<(), SystemError>;
|
||||||
|
@ -13,9 +13,8 @@ use crate::{
|
|||||||
},
|
},
|
||||||
include::bindings::bindings::{
|
include::bindings::bindings::{
|
||||||
pid_t, process_control_block, process_do_exit, process_find_pcb_by_pid, pt_regs,
|
pid_t, process_control_block, process_do_exit, process_find_pcb_by_pid, pt_regs,
|
||||||
spinlock_t, verify_area, NULL, PF_EXITING,
|
spinlock_t, verify_area, NULL, PF_EXITING, PF_KTHREAD, PF_SIGNALED, PF_WAKEKILL,
|
||||||
PF_KTHREAD, PF_SIGNALED, PF_WAKEKILL, PROC_INTERRUPTIBLE, USER_CS, USER_DS,
|
PROC_INTERRUPTIBLE, USER_CS, USER_DS, USER_MAX_LINEAR_ADDR,
|
||||||
USER_MAX_LINEAR_ADDR,
|
|
||||||
},
|
},
|
||||||
ipc::signal_types::{sigset_add, user_sigaction},
|
ipc::signal_types::{sigset_add, user_sigaction},
|
||||||
kBUG, kdebug, kerror, kwarn,
|
kBUG, kdebug, kerror, kwarn,
|
||||||
@ -29,7 +28,8 @@ use crate::{
|
|||||||
process::{
|
process::{
|
||||||
pid::PidType,
|
pid::PidType,
|
||||||
process::{process_is_stopped, process_kick, process_wake_up_state},
|
process::{process_is_stopped, process_kick, process_wake_up_state},
|
||||||
}, syscall::SystemError,
|
},
|
||||||
|
syscall::SystemError,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::signal_types::{
|
use super::signal_types::{
|
||||||
@ -725,7 +725,11 @@ fn setup_frame(
|
|||||||
regs.cs = (USER_CS | 0x3) as u64;
|
regs.cs = (USER_CS | 0x3) as u64;
|
||||||
regs.ds = (USER_DS | 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)]
|
#[inline(always)]
|
||||||
@ -762,7 +766,11 @@ fn copy_siginfo_to_user(to: *mut siginfo, from: &siginfo) -> Result<i32, SystemE
|
|||||||
/// @param context 要被设置的目标sigcontext
|
/// @param context 要被设置的目标sigcontext
|
||||||
/// @param mask 要被暂存的信号mask标志位
|
/// @param mask 要被暂存的信号mask标志位
|
||||||
/// @param regs 进入信号处理流程前,Restore all要弹出的内核栈栈帧
|
/// @param regs 进入信号处理流程前,Restore all要弹出的内核栈栈帧
|
||||||
fn setup_sigcontext(context: &mut sigcontext, mask: &sigset_t, regs: &pt_regs) -> Result<i32, SystemError> {
|
fn setup_sigcontext(
|
||||||
|
context: &mut sigcontext,
|
||||||
|
mask: &sigset_t,
|
||||||
|
regs: &pt_regs,
|
||||||
|
) -> Result<i32, SystemError> {
|
||||||
let current_thread = current_pcb().thread;
|
let current_thread = current_pcb().thread;
|
||||||
|
|
||||||
context.oldmask = *mask;
|
context.oldmask = *mask;
|
||||||
@ -934,7 +942,6 @@ pub extern "C" fn sys_sigaction(regs: &mut pt_regs) -> u64 {
|
|||||||
} else {
|
} else {
|
||||||
return retval.unwrap_err().to_posix_errno() as u64;
|
return retval.unwrap_err().to_posix_errno() as u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_sigaction(
|
fn do_sigaction(
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
/// 导出x86_64架构相关的代码,命名为arch模块
|
/// 导出x86_64架构相关的代码,命名为arch模块
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
#[path = "arch/x86_64/mod.rs"]
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod arch;
|
mod arch;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use super::spinlock::RawSpinlock;
|
use super::spinlock::RawSpinlock;
|
||||||
use crate::{
|
use crate::{arch::asm::cmpxchg::try_cmpxchg_q, syscall::SystemError};
|
||||||
arch::asm::cmpxchg::try_cmpxchg_q,
|
|
||||||
syscall::SystemError,
|
|
||||||
};
|
|
||||||
use core::{fmt::Debug, intrinsics::size_of};
|
use core::{fmt::Debug, intrinsics::size_of};
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -53,7 +50,7 @@ impl LockRef {
|
|||||||
fn cmpxchg_loop(&mut self, mode: CmpxchgMode) -> Result<i32, i32> {
|
fn cmpxchg_loop(&mut self, mode: CmpxchgMode) -> Result<i32, i32> {
|
||||||
use core::ptr::read_volatile;
|
use core::ptr::read_volatile;
|
||||||
|
|
||||||
use crate::{arch::cpu::cpu_relax};
|
use crate::arch::cpu::cpu_relax;
|
||||||
|
|
||||||
let mut old: LockRef = LockRef::INIT;
|
let mut old: LockRef = LockRef::INIT;
|
||||||
old.count = unsafe { read_volatile(&self.count) };
|
old.count = unsafe { read_volatile(&self.count) };
|
||||||
|
@ -10,7 +10,8 @@ use crate::{
|
|||||||
include::bindings::bindings::{
|
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;
|
use super::spinlock::SpinLock;
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use core::cmp::Ord;
|
use core::cmp::Ord;
|
||||||
use core::fmt::{self, Debug};
|
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use core::ptr;
|
use core::fmt::{self, Debug};
|
||||||
use core::iter::{IntoIterator, FromIterator};
|
use core::iter::{FromIterator, IntoIterator};
|
||||||
use core::marker;
|
use core::marker;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::ops::Index;
|
use core::ops::Index;
|
||||||
|
use core::ptr;
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
@ -234,7 +234,6 @@ impl<K: Ord, V> NodePtr<K, V> {
|
|||||||
unsafe { (*self.0).right = right }
|
unsafe { (*self.0).right = right }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn parent(&self) -> NodePtr<K, V> {
|
fn parent(&self) -> NodePtr<K, V> {
|
||||||
if self.is_null() {
|
if self.is_null() {
|
||||||
@ -421,9 +420,8 @@ where
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.iter().all(|(key, value)| {
|
self.iter()
|
||||||
other.get(key).map_or(false, |v| *value == *v)
|
.all(|(key, value)| other.get(key).map_or(false, |v| *value == *v))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +444,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<K: Ord, V> FromIterator<(K, V)> for RBTree<K, V> {
|
impl<K: Ord, V> FromIterator<(K, V)> for RBTree<K, V> {
|
||||||
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> RBTree<K, V> {
|
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> RBTree<K, V> {
|
||||||
let mut tree = RBTree::new();
|
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> {
|
impl<'a, K: Ord, V> Clone for Keys<'a, K, V> {
|
||||||
fn clone(&self) -> 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> {
|
impl<'a, K: Ord, V> Clone for Values<'a, K, V> {
|
||||||
fn clone(&self) -> 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> {
|
impl<'a, K: Ord, V> Iterator for Values<'a, K, V> {
|
||||||
type Item = &'a 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> {
|
impl<'a, K: Ord, V> Clone for ValuesMut<'a, K, V> {
|
||||||
fn clone(&self) -> ValuesMut<'a, K, V> {
|
fn clone(&self) -> ValuesMut<'a, K, V> {
|
||||||
ValuesMut { inner: self.inner.clone() }
|
ValuesMut {
|
||||||
|
inner: self.inner.clone(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,7 +814,6 @@ impl<'a, K: Ord + 'a, V: 'a> DoubleEndedIterator for IterMut<'a, K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<K: Ord, V> IntoIterator for RBTree<K, V> {
|
impl<K: Ord, V> IntoIterator for RBTree<K, V> {
|
||||||
type Item = (K, V);
|
type Item = (K, V);
|
||||||
type IntoIter = IntoIter<K, V>;
|
type IntoIter = IntoIter<K, V>;
|
||||||
@ -1387,7 +1388,9 @@ impl<K: Ord, V> RBTree<K, V> {
|
|||||||
/// Return the value iter mut
|
/// Return the value iter mut
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn values_mut(&mut self) -> ValuesMut<K, V> {
|
pub fn values_mut(&mut self) -> ValuesMut<K, V> {
|
||||||
ValuesMut { inner: self.iter_mut() }
|
ValuesMut {
|
||||||
|
inner: self.iter_mut(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the key and value iter
|
/// Return the key and value iter
|
||||||
@ -1441,7 +1444,6 @@ mod tests {
|
|||||||
assert_eq!(*m.get(&2).unwrap(), 6);
|
assert_eq!(*m.get(&2).unwrap(), 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_clone() {
|
fn test_clone() {
|
||||||
let mut m = RBTree::new();
|
let mut m = RBTree::new();
|
||||||
|
@ -7,7 +7,7 @@ use core::{
|
|||||||
sync::atomic::{AtomicU32, Ordering},
|
sync::atomic::{AtomicU32, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{syscall::SystemError};
|
use crate::syscall::SystemError;
|
||||||
|
|
||||||
///RwLock读写锁
|
///RwLock读写锁
|
||||||
|
|
||||||
|
@ -147,6 +147,7 @@ void system_initialize()
|
|||||||
// ps2_mouse_init();
|
// ps2_mouse_init();
|
||||||
// ata_init();
|
// ata_init();
|
||||||
pci_init();
|
pci_init();
|
||||||
|
rs_pci_init();
|
||||||
io_mfence();
|
io_mfence();
|
||||||
|
|
||||||
// test_slab();
|
// test_slab();
|
||||||
|
@ -4,8 +4,8 @@ use crate::{
|
|||||||
arch::asm::current::current_pcb,
|
arch::asm::current::current_pcb,
|
||||||
include::bindings::bindings::{
|
include::bindings::bindings::{
|
||||||
initial_mm, mm_create_vma, mm_unmap, vm_area_del, vm_area_free, vm_area_struct, vm_flags_t,
|
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,
|
vma_find, MMIO_BASE, MMIO_TOP, PAGE_1G_SHIFT, PAGE_1G_SIZE, PAGE_2M_SIZE, PAGE_4K_SHIFT,
|
||||||
PAGE_2M_SIZE, PAGE_4K_SHIFT, PAGE_4K_SIZE, VM_DONTCOPY, VM_IO,
|
PAGE_4K_SIZE, VM_DONTCOPY, VM_IO,
|
||||||
},
|
},
|
||||||
kdebug, kerror,
|
kdebug, kerror,
|
||||||
};
|
};
|
||||||
|
@ -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 allocator;
|
||||||
pub mod gfp;
|
pub mod gfp;
|
||||||
|
@ -16,7 +16,8 @@ use crate::{
|
|||||||
ffi_convert::FFIBind2Rust,
|
ffi_convert::FFIBind2Rust,
|
||||||
refcount::{refcount_inc, RefCount},
|
refcount::{refcount_inc, RefCount},
|
||||||
spinlock::{spin_lock_irqsave, spin_unlock_irqrestore},
|
spinlock::{spin_lock_irqsave, spin_unlock_irqrestore},
|
||||||
}, syscall::SystemError,
|
},
|
||||||
|
syscall::SystemError,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
use num_traits::{FromPrimitive, ToPrimitive};
|
use num_traits::{FromPrimitive, ToPrimitive};
|
||||||
|
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user