Better module usage in zircon-object/dev/pci

This commit is contained in:
Yuekai Jia 2021-09-03 17:57:53 +08:00
parent dee715c4a2
commit 5c33799a04
15 changed files with 139 additions and 87 deletions

View File

@ -25,6 +25,7 @@ xmas-elf = { version = "0.7", optional = true }
region-alloc = { git = "https://github.com/rzswh/region-allocator", rev = "122c7a71" }
lazy_static = { version = "1.4", features = ["spin_no_std" ] }
acpi = "1.1"
cfg-if = "1.0"
#rvm = { git = "https://github.com/rcore-os/RVM", rev = "382fc60", optional = true }
[dev-dependencies]

View File

@ -2,7 +2,7 @@ use {
self::event_interrupt::*,
self::pci_interrupt::*,
self::virtual_interrupt::*,
super::IPciNode,
crate::dev::pci::IPciNode,
crate::object::*,
crate::signal::*,
alloc::{boxed::Box, sync::Arc},

View File

@ -1,4 +1,9 @@
use {super::super::pci::PCIE_IRQRET_MASK, super::super::IPciNode, super::*, spin::Mutex};
use alloc::{boxed::Box, sync::Arc};
use spin::Mutex;
use super::InterruptTrait;
use crate::dev::pci::{constants::PCIE_IRQRET_MASK, IPciNode};
use crate::{ZxError, ZxResult};
pub struct PciInterrupt {
device: Arc<dyn IPciNode>,

View File

@ -1,11 +1,10 @@
//! Objects for Device Drivers.
use super::*;
mod bti;
mod interrupt;
mod iommu;
mod pci;
pub mod pci;
mod pmt;
mod resource;
pub use self::{bti::*, interrupt::*, iommu::*, pci::*, pmt::*, resource::*};
pub use self::{bti::*, interrupt::*, iommu::*, pmt::*, resource::*};

View File

@ -1,9 +1,18 @@
use super::super::*;
use super::config::*;
use super::*;
use super::nodes::{
IPciNode, PciNodeType, PciRoot, PcieBarInfo, PcieIrqMode, PcieIrqModeCaps,
SharedLegacyIrqHandler,
};
use super::{
config::PciConfig, constants::*, pci_init_args::PciIrqSwizzleLut, pio::pci_bdf_raw_addr,
MappedEcamRegion, PciAddrSpace, PciEcamRegion,
};
use crate::dev::Interrupt;
use crate::object::*;
use crate::vm::{kernel_allocate_physical, CachePolicy, MMUFlags, PhysAddr, VirtAddr};
use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
use crate::ZxResult;
use alloc::sync::{Arc, Weak};
use alloc::{collections::BTreeMap, vec::Vec};
use core::cmp::min;
use core::marker::{Send, Sync};
use lazy_static::*;

View File

@ -1,6 +1,6 @@
use super::super::{ZxError, ZxResult};
use super::config::PciConfig;
use super::nodes::PcieDeviceType;
use super::{config::PciConfig, nodes::PcieDeviceType};
use crate::{ZxError, ZxResult};
use alloc::boxed::Box;
use core::convert::TryFrom;
use kernel_hal::InterruptManager;

View File

@ -1,5 +1,6 @@
use super::*;
use numeric_enum_macro::*;
use super::pio::{pio_config_read_addr, pio_config_write_addr};
use super::PciAddrSpace;
use numeric_enum_macro::numeric_enum;
#[derive(Debug)]
pub struct PciConfig {

View File

@ -1,3 +1,5 @@
#![allow(missing_docs)]
mod bus;
mod caps;
mod config;
@ -5,17 +7,11 @@ mod nodes;
pub mod pci_init_args;
mod pio;
use super::*;
use alloc::sync::*;
pub(crate) use nodes::*;
use pci_init_args::*;
use pio::*;
pub use self::bus::{
MmioPcieAddressProvider, PCIeBusDriver, PcieDeviceInfo, PcieDeviceKObject,
PioPcieAddressProvider,
};
pub use self::nodes::PcieIrqMode;
pub use self::nodes::{IPciNode, PcieIrqMode};
pub use self::pio::{pio_config_read, pio_config_write};
/// Type of PCI address space.
@ -46,10 +42,8 @@ pub struct MappedEcamRegion {
vaddr: u64,
}
pub use constants::*;
#[allow(missing_docs)]
mod constants {
pub mod constants {
pub const PCI_MAX_DEVICES_PER_BUS: usize = 32;
pub const PCI_MAX_FUNCTIONS_PER_DEVICE: usize = 8;
pub const PCI_MAX_LEGACY_IRQ_PINS: usize = 4;

View File

@ -1,12 +1,22 @@
#![allow(dead_code)]
#![allow(missing_docs)]
use super::{caps::*, config::*, *};
use crate::vm::PAGE_SIZE;
use alloc::{boxed::Box, sync::*, vec::Vec};
use super::caps::{
PciCapAdvFeatures, PciCapPcie, PciCapability, PciCapabilityMsi, PciCapabilityStd, PciMsiBlock,
};
use super::config::{
PciConfig, PciReg16, PciReg32, PciReg8, PCIE_BASE_CONFIG_SIZE, PCIE_EXTENDED_CONFIG_SIZE,
};
use super::constants::*;
use super::{bus::PCIeBusDriver, pci_init_args::PciIrqSwizzleLut};
use crate::{vm::PAGE_SIZE, ZxError, ZxResult};
use alloc::sync::{Arc, Weak};
use alloc::{boxed::Box, vec::Vec};
use kernel_hal::InterruptManager;
use numeric_enum_macro::*;
use numeric_enum_macro::numeric_enum;
use region_alloc::RegionAllocator;
use spin::*;
use spin::{Mutex, MutexGuard};
numeric_enum! {
#[repr(u8)]
@ -953,7 +963,7 @@ impl PcieDevice {
}))
}
}
fn enable_msi_irq_mode(&self, inner: &mut MutexGuard<PcieDeviceInner>, irq: u32) -> ZxResult {
fn enter_msi_irq_mode(&self, inner: &mut MutexGuard<PcieDeviceInner>, irq: u32) -> ZxResult {
let (_std, msi) = inner.msi().ok_or(ZxError::NOT_SUPPORTED)?;
let initially_masked = if msi.has_pvm {
self.cfg
@ -1134,7 +1144,7 @@ impl PcieDevice {
inner.irq.legacy.shared_handler.add_device(inner.arc_self());
Ok(())
}
PcieIrqMode::Msi => self.enable_msi_irq_mode(&mut inner, irq_count),
PcieIrqMode::Msi => self.enter_msi_irq_mode(&mut inner, irq_count),
PcieIrqMode::MsiX => Err(ZxError::NOT_SUPPORTED),
_ => Err(ZxError::INVALID_ARGS),
}

View File

@ -3,6 +3,9 @@
//!
//! reference: zircon/system/public/zircon/syscalls/pci.h
use super::constants::*;
use crate::{ZxError, ZxResult};
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct PciIrqSwizzleLut(
@ -42,7 +45,6 @@ pub const PCI_INIT_ARG_MAX_SIZE: usize = core::mem::size_of::<PciInitArgsAddrWin
* PCI_INIT_ARG_MAX_ECAM_WINDOWS
+ core::mem::size_of::<PciInitArgsHeader>();
use super::*;
use kernel_hal::InterruptManager;
impl PciInitArgsHeader {

View File

@ -1,12 +1,6 @@
#![allow(missing_docs)]
use super::super::*;
use kernel_hal::{inpd, outpd};
use spin::Mutex;
static PIO_LOCK: Mutex<()> = Mutex::new(());
const PCI_CONFIG_ADDR: u16 = 0xcf8;
const PCI_CONFIG_DATA: u16 = 0xcfc;
const PCI_CONFIG_ENABLE: u32 = 1 << 31;
use crate::{ZxError, ZxResult};
/// Returns the BDF address without the bottom two bits masked off.
pub fn pci_bdf_raw_addr(bus: u8, dev: u8, func: u8, offset: u8) -> u32 {
@ -16,9 +10,15 @@ pub fn pci_bdf_raw_addr(bus: u8, dev: u8, func: u8, offset: u8) -> u32 {
| (offset as u32 & 0xff) // bits 7-2 reg, with bottom 2 bits as well
}
pub fn pio_config_read(bus: u8, dev: u8, func: u8, offset: u8, width: usize) -> ZxResult<u32> {
pio_config_read_addr(pci_bdf_raw_addr(bus, dev, func, offset), width)
}
cfg_if::cfg_if! {
if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
use kernel_hal::{inpd, outpd};
use spin::Mutex;
static PIO_LOCK: Mutex<()> = Mutex::new(());
const PCI_CONFIG_ADDR: u16 = 0xcf8;
const PCI_CONFIG_DATA: u16 = 0xcfc;
const PCI_CONFIG_ENABLE: u32 = 1 << 31;
pub fn pio_config_read_addr(addr: u32, width: usize) -> ZxResult<u32> {
let _lock = PIO_LOCK.lock();
@ -30,18 +30,6 @@ pub fn pio_config_read_addr(addr: u32, width: usize) -> ZxResult<u32> {
let tmp_val = u32::from_le(inpd(PCI_CONFIG_DATA));
Ok((tmp_val >> shift) & (((1u64 << width) - 1) as u32))
}
pub fn pio_config_write(
bus: u8,
dev: u8,
func: u8,
offset: u8,
val: u32,
width: usize,
) -> ZxResult {
pio_config_write_addr(pci_bdf_raw_addr(bus, dev, func, offset), val, width)
}
pub fn pio_config_write_addr(addr: u32, val: u32, width: usize) -> ZxResult {
let _lock = PIO_LOCK.lock();
let shift = ((addr & 0x3) << 3) as usize;
@ -59,3 +47,27 @@ pub fn pio_config_write_addr(addr: u32, val: u32, width: usize) -> ZxResult {
outpd(PCI_CONFIG_DATA, u32::to_le(tmp_val));
Ok(())
}
} else {
pub fn pio_config_read_addr(_addr: u32, _width: usize) -> ZxResult<u32> {
Err(ZxError::NOT_SUPPORTED)
}
pub fn pio_config_write_addr(_addr: u32, _val: u32, _width: usize) -> ZxResult {
Err(ZxError::NOT_SUPPORTED)
}
}
} // cfg_if!
pub fn pio_config_read(bus: u8, dev: u8, func: u8, offset: u8, width: usize) -> ZxResult<u32> {
pio_config_read_addr(pci_bdf_raw_addr(bus, dev, func, offset), width)
}
pub fn pio_config_write(
bus: u8,
dev: u8,
func: u8,
offset: u8,
val: u32,
width: usize,
) -> ZxResult {
pio_config_write_addr(pci_bdf_raw_addr(bus, dev, func, offset), val, width)
}

View File

@ -22,4 +22,4 @@ numeric-enum-macro = "0.2"
zircon-object = { path = "../zircon-object" }
kernel-hal = { path = "../kernel-hal" }
futures = { version = "0.3", default-features = false, features = ["alloc", "async-await"] }
cfg-if = "1.0"

View File

@ -132,6 +132,7 @@ impl Syscall<'_> {
}
///
#[allow(unused_variables, unused_mut)]
pub fn sys_pc_firmware_tables(
&self,
resource: HandleValue,
@ -142,10 +143,16 @@ impl Syscall<'_> {
let proc = self.thread.proc();
proc.get_object::<Resource>(resource)?
.validate(ResourceKind::ROOT)?;
cfg_if::cfg_if! {
if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
let (acpi_rsdp, smbios) = kernel_hal::pc_firmware_tables();
acpi_rsdp_ptr.write(acpi_rsdp)?;
smbios_ptr.write(smbios)?;
Ok(())
} else {
Err(ZxError::NOT_SUPPORTED)
}
}
}
/// Creates an interrupt object which represents a physical or virtual interrupt.

View File

@ -322,7 +322,6 @@ impl Syscall<'_> {
Sys::PCI_ADD_SUBTRACT_IO_RANGE => {
self.sys_pci_add_subtract_io_range(a0 as _, a1 != 0, a2 as _, a3 as _, a4 != 0)
}
#[cfg(target_arch = "x86_64")]
Sys::PCI_CFG_PIO_RW => self.sys_pci_cfg_pio_rw(
a0 as _,
a1 as _,

View File

@ -1,7 +1,14 @@
use super::*;
use alloc::sync::Arc;
use core::convert::TryFrom;
use zircon_object::{
dev::{pci_init_args::*, *},
dev::pci::{
constants::*,
pci_init_args::{PciInitArgsAddrWindows, PciInitArgsHeader, PCI_INIT_ARG_MAX_SIZE},
MmioPcieAddressProvider, PCIeBusDriver, PciAddrSpace, PciEcamRegion, PcieDeviceInfo,
PcieDeviceKObject, PcieIrqMode, PioPcieAddressProvider,
},
dev::{Resource, ResourceKind},
vm::{pages, VmObject},
};
@ -33,8 +40,7 @@ impl Syscall<'_> {
}
}
#[allow(clippy::too_many_arguments)]
#[cfg(target_arch = "x86_64")]
#[allow(clippy::too_many_arguments, unused_variables, unused_mut)]
pub fn sys_pci_cfg_pio_rw(
&self,
handle: HandleValue,
@ -50,6 +56,9 @@ impl Syscall<'_> {
"pci.cfg_pio_rw: handle={:#x}, addr={:x}:{:x}:{:x}, offset={:#x}, width={:#x}, write={:#}",
handle, bus, dev, func, offset, width, write
);
cfg_if::cfg_if! {
if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
use zircon_object::dev::pci::{pio_config_read, pio_config_write};
let proc = self.thread.proc();
proc.get_object::<Resource>(handle)?
.validate(ResourceKind::ROOT)?;
@ -61,6 +70,10 @@ impl Syscall<'_> {
value_ptr.write(value)?;
}
Ok(())
} else {
Err(ZxError::NOT_SUPPORTED)
}
}
}
// TODO: review