mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
修复ecam无法获取MCFG table的问题 (#241)
This commit is contained in:
parent
79a452ce8f
commit
5c1e552cc7
@ -3,7 +3,7 @@ pub mod 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};
|
||||
use crate::driver::pci::pci::{BusDeviceFunction, PciAddr, PciError, PciRoot, SegmentGroupNumber};
|
||||
/// TraitPciArch Pci架构相关函数,任何架构都应独立实现trait里的函数
|
||||
pub trait TraitPciArch {
|
||||
/// @brief 读取寄存器值,x86_64架构通过读取两个特定io端口实现
|
||||
@ -18,8 +18,8 @@ pub trait TraitPciArch {
|
||||
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>;
|
||||
/// @return usize 转换结果
|
||||
fn address_pci_to_physical(pci_address: PciAddr) -> usize;
|
||||
/// @brief 获取Segement的root地址,x86_64架构为acpi mcfg表中读取
|
||||
/// @param segement 组id
|
||||
/// @return Result<PciRoot, PciError> 转换结果或出错原因
|
||||
|
@ -1,7 +1,7 @@
|
||||
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,
|
||||
BusDeviceFunction, PciAddr, PciError, PciRoot, SegmentGroupNumber, PORT_PCI_CONFIG_ADDRESS,
|
||||
PORT_PCI_CONFIG_DATA,
|
||||
};
|
||||
use crate::include::bindings::bindings::{
|
||||
@ -40,8 +40,8 @@ impl TraitPciArch for X86_64PciArch {
|
||||
}
|
||||
}
|
||||
|
||||
fn address_pci_to_address_memory(address: usize) -> Result<usize, PciError> {
|
||||
Ok(address)
|
||||
fn address_pci_to_physical(pci_address: PciAddr) -> usize {
|
||||
return pci_address.data();
|
||||
}
|
||||
|
||||
fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError> {
|
||||
|
@ -11,10 +11,12 @@ 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},
|
||||
fmt::{self, Debug, Display, Formatter},
|
||||
};
|
||||
|
||||
// PCI_DEVICE_LINKEDLIST 添加了读写锁的全局链表,里面存储了检索到的PCI设备结构体
|
||||
// PCI_ROOT_0 Segment为0的全局PciRoot
|
||||
lazy_static! {
|
||||
@ -29,6 +31,40 @@ lazy_static! {
|
||||
}
|
||||
};
|
||||
}
|
||||
/// PCI域地址
|
||||
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
|
||||
#[repr(transparent)]
|
||||
pub struct PciAddr(usize);
|
||||
|
||||
impl PciAddr {
|
||||
#[inline(always)]
|
||||
pub const fn new(address: usize) -> Self {
|
||||
Self(address)
|
||||
}
|
||||
|
||||
/// @brief 获取PCI域地址的值
|
||||
#[inline(always)]
|
||||
pub fn data(&self) -> usize {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// @brief 将PCI域地址加上一个偏移量
|
||||
#[inline(always)]
|
||||
pub fn add(self, offset: usize) -> Self {
|
||||
Self(self.0 + offset)
|
||||
}
|
||||
|
||||
/// @brief 判断PCI域地址是否按照指定要求对齐
|
||||
#[inline(always)]
|
||||
pub fn check_aligned(&self, align: usize) -> bool {
|
||||
return self.0 & (align - 1) == 0;
|
||||
}
|
||||
}
|
||||
impl Debug for PciAddr {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "PciAddr({:#x})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// 添加了读写锁的链表,存储PCI设备结构体
|
||||
pub struct PciDeviceLinkedList {
|
||||
@ -489,7 +525,7 @@ 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}",
|
||||
"PCI Root with segement:{}, bus begin at {}, bus end at {}, physical address at {:#x},mapped at {:#x}",
|
||||
self.segement_group_number, self.bus_begin, self.bus_end, self.physical_address_base, self.mmio_base.unwrap() as usize
|
||||
)
|
||||
}
|
||||
@ -506,13 +542,14 @@ impl PciRoot {
|
||||
/// @brief 完成物理地址到虚拟地址的映射,并将虚拟地址加入mmio_base变量
|
||||
/// @return 返回错误或Ok(0)
|
||||
fn map(&mut self) -> Result<u8, PciError> {
|
||||
let bus_number = self.bus_end - self.bus_begin + 1;
|
||||
let bus_number_double = (bus_number + 1) / 2;
|
||||
//kdebug!("bus_begin={},bus_end={}", self.bus_begin,self.bus_end);
|
||||
let bus_number = (self.bus_end - self.bus_begin) as u32 + 1;
|
||||
let bus_number_double = (bus_number - 1) / 2 + 1; //一个bus占据1MB空间,计算全部bus占据空间相对于2MB空间的个数
|
||||
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;
|
||||
let size = bus_number_double * PAGE_2M_SIZE;
|
||||
unsafe {
|
||||
let initial_mm_ptr = &mut initial_mm as *mut mm_struct;
|
||||
if let Err(_) =
|
||||
@ -978,7 +1015,19 @@ fn pci_check_bus(bus: u8) -> Result<u8, PciError> {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rs_pci_init() {
|
||||
pci_init();
|
||||
//kdebug!("{}",PCI_ROOT_0.unwrap());
|
||||
if PCI_ROOT_0.is_some() {
|
||||
kdebug!("{}", PCI_ROOT_0.unwrap());
|
||||
//以下为ecam的读取寄存器值测试,经测试可正常读取
|
||||
// let bus_device_function = BusDeviceFunction {
|
||||
// bus: 0,
|
||||
// device: 2,
|
||||
// function: 0,
|
||||
// };
|
||||
// kdebug!(
|
||||
// "Ecam read virtio-net device status={:#x}",
|
||||
// (PCI_ROOT_0.unwrap().read_config(bus_device_function, 4)>>16) as u16
|
||||
// );
|
||||
}
|
||||
}
|
||||
/// @brief pci初始化函数
|
||||
pub fn pci_init() {
|
||||
@ -996,7 +1045,7 @@ pub fn pci_init() {
|
||||
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);
|
||||
kinfo!("Found pci standard device with class code ={} subclass={} status={:#x} cap_pointer={:#x} vendor={:#x}, device id={:#x},bdf={}", 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,common_header.bus_device_function);
|
||||
}
|
||||
HeaderType::Standard => {
|
||||
kinfo!(
|
||||
@ -1055,7 +1104,11 @@ impl BusDeviceFunction {
|
||||
///实现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)
|
||||
write!(
|
||||
f,
|
||||
"bus {} device {} function{}",
|
||||
self.bus, self.device, self.function
|
||||
)
|
||||
}
|
||||
}
|
||||
/// The location allowed for a memory BAR.
|
||||
@ -1267,7 +1320,8 @@ pub fn pci_bar_init(
|
||||
address |= u64::from(address_top) << 32;
|
||||
bar_index_ignore = bar_index + 1; //下个bar跳过,因为64位的memory bar覆盖了两个bar
|
||||
}
|
||||
//kdebug!("address={:#x},size={:#x}",address,size);
|
||||
let pci_address = PciAddr::new(address as usize);
|
||||
address = PciArch::address_pci_to_physical(pci_address) as u64; //PCI总线域物理地址转换为存储器域物理地址
|
||||
unsafe {
|
||||
let vaddr_ptr = &mut virtaddress as *mut u64;
|
||||
let mut virtsize: u64 = 0;
|
||||
|
@ -9,7 +9,6 @@ use crate::libs::rwlock::RwLockWriteGuard;
|
||||
use crate::{kdebug, kerror, kwarn};
|
||||
use alloc::{boxed::Box, collections::LinkedList};
|
||||
use virtio_drivers::transport::{DeviceType, Transport};
|
||||
|
||||
const NETWORK_CLASS: u8 = 0x2;
|
||||
const ETHERNET_SUBCLASS: u8 = 0x0;
|
||||
|
||||
|
@ -29,7 +29,7 @@ QEMU_RTC_CLOCK="clock=host,base=localtime"
|
||||
QEMU_SERIAL="file:../serial_opt.txt"
|
||||
QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none"
|
||||
|
||||
QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -nic user,model=virtio-net-pci -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel}"
|
||||
QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -nic user,model=virtio-net-pci -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35"
|
||||
|
||||
QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user