mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-21 00:06:32 +00:00
pci重构+pcie支持 (#235)
* pci重构+pcie支持 * pci重构测试完成 * 修正makefile的问题 * 小修改 * 修改函数名字
This commit is contained in:
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 super::fpu::{fp_state_save, fp_state_restore};
|
||||
use super::fpu::{fp_state_restore, fp_state_save};
|
||||
|
||||
/// @brief 切换进程的上下文(没有切换页表的动作)
|
||||
///
|
||||
|
@ -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;
|
||||
|
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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user