refactor(drivers): 修改 io

- 根据 wikipedia,pio 改名 pmio
- 为 mmio 读写增加内存屏障
- 为 io 补充文档
This commit is contained in:
YdrMaster 2022-04-09 22:57:33 +08:00
parent fcc46ebfc5
commit 99f21ba488
14 changed files with 141 additions and 106 deletions

View File

@ -1,12 +1,10 @@
use core::mem::MaybeUninit; use super::Io;
use core::ops::{BitAnd, BitOr, Not}; use core::ops::{BitAnd, BitOr, Not};
use super::Io; // 主存映射 I/O。
/// Memory-mapped I/O.
#[repr(transparent)] #[repr(transparent)]
pub struct Mmio<T> { pub struct Mmio<T>(T);
value: MaybeUninit<T>,
}
impl<T> Mmio<T> { impl<T> Mmio<T> {
/// # Safety /// # Safety
@ -25,9 +23,7 @@ impl<T> Mmio<T> {
} }
pub fn add<'a>(&self, offset: usize) -> &'a mut Self { pub fn add<'a>(&self, offset: usize) -> &'a mut Self {
unsafe { unsafe { Self::from_base((&self.0 as *const T).add(offset) as _) }
Self::from_base(self.value.as_ptr() as usize + offset * core::mem::size_of::<T>())
}
} }
} }
@ -38,10 +34,19 @@ where
type Value = T; type Value = T;
fn read(&self) -> T { fn read(&self) -> T {
unsafe { core::ptr::read_volatile(self.value.as_ptr()) } unsafe {
let val = core::ptr::read_volatile(&self.0 as *const _);
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
core::arch::asm!("fence i,r");
val
}
} }
fn write(&mut self, value: T) { fn write(&mut self, value: T) {
unsafe { core::ptr::write_volatile(self.value.as_mut_ptr(), value) }; unsafe {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
core::arch::asm!("fence w,o");
core::ptr::write_volatile(&mut self.0 as *mut _, value)
};
} }
} }

View File

@ -1,57 +1,79 @@
//! General MMIO and PIO device driver. // 封装对外设地址空间的访问,包括内存映射 IO 和端口映射 IO。
//
// 要了解这两种访问外设的方式,查看[维基百科](https://en.wikipedia.org/wiki/Memory-mapped_I/O)。
//! Peripheral address space access, including memory-mapped IO and port-mapped IO.
//!
//! About these two methods of performing I/O, see [wikipedia](https://en.wikipedia.org/wiki/Memory-mapped_I/O).
use core::ops::{BitAnd, BitOr, Not}; use core::ops::{BitAnd, BitOr, Not};
mod mmio; mod mmio;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
mod pio; mod pmio;
pub use mmio::Mmio; pub use mmio::Mmio;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub use pio::Pio; pub use pmio::Pmio;
// 用于处理外设地址空间访问的接口。
/// An interface for dealing with device address space access.
pub trait Io { pub trait Io {
// 可访问的对象的类型。
/// The type of object to access.
type Value: Copy type Value: Copy
+ BitAnd<Output = Self::Value> + BitAnd<Output = Self::Value>
+ BitOr<Output = Self::Value> + BitOr<Output = Self::Value>
+ Not<Output = Self::Value>; + Not<Output = Self::Value>;
// 从外设读取值。
/// Reads value from device.
fn read(&self) -> Self::Value; fn read(&self) -> Self::Value;
// 向外设写入值。
/// Writes `value` to device.
fn write(&mut self, value: Self::Value); fn write(&mut self, value: Self::Value);
} }
// 外设地址空间的一个只读单元。
/// A readonly unit in device address space.
#[repr(transparent)] #[repr(transparent)]
pub struct ReadOnly<I> { pub struct ReadOnly<I>(I);
inner: I,
}
impl<I> ReadOnly<I> { impl<I> ReadOnly<I> {
pub const fn new(inner: I) -> ReadOnly<I> { // 构造外设地址空间的一个只读单元。
ReadOnly { inner } /// Constructs a readonly unit in device address space.
pub const fn new(inner: I) -> Self {
Self(inner)
} }
} }
impl<I: Io> ReadOnly<I> { impl<I: Io> ReadOnly<I> {
// 从外设读取值。
/// Reads value from device.
#[inline(always)] #[inline(always)]
pub fn read(&self) -> I::Value { pub fn read(&self) -> I::Value {
self.inner.read() self.0.read()
} }
} }
// 外设地址空间的一个只写单元。
/// A write-only unit in device address space.
#[repr(transparent)] #[repr(transparent)]
pub struct WriteOnly<I> { pub struct WriteOnly<I>(I);
inner: I,
}
impl<I> WriteOnly<I> { impl<I> WriteOnly<I> {
pub const fn new(inner: I) -> WriteOnly<I> { // 构造外设地址空间的一个只写单元。
WriteOnly { inner } /// Constructs a write-only unit in device address space.
pub const fn new(inner: I) -> Self {
Self(inner)
} }
} }
impl<I: Io> WriteOnly<I> { impl<I: Io> WriteOnly<I> {
// 向外设写入值。
/// Writes `value` to device.
#[inline(always)] #[inline(always)]
pub fn write(&mut self, value: I::Value) { pub fn write(&mut self, value: I::Value) {
self.inner.write(value) self.0.write(value);
} }
} }

View File

@ -1,30 +1,35 @@
use core::arch::asm; // 端口映射 I/O。
use core::marker::PhantomData; //! Port-mapped I/O.
use super::Io; use super::Io;
use core::{arch::asm, marker::PhantomData};
/// Generic PIO // 端口映射 I/O。
/// Port-mapped I/O.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Pio<T> { pub struct Pmio<T> {
port: u16, port: u16,
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T> Pio<T> { impl<T> Pmio<T> {
/// Create a PIO from a given port // 映射指定端口进行外设访问。
/// Maps a given port to assess device.
pub const fn new(port: u16) -> Self { pub const fn new(port: u16) -> Self {
Pio::<T> { Self {
port, port,
_phantom: PhantomData, _phantom: PhantomData,
} }
} }
} }
/// Read/Write for byte PIO // 逐字节端口映射读写。
impl Io for Pio<u8> { /// Read/Write for byte PMIO.
impl Io for Pmio<u8> {
type Value = u8; type Value = u8;
/// Read // 读。
/// Read.
#[inline(always)] #[inline(always)]
fn read(&self) -> u8 { fn read(&self) -> u8 {
let value: u8; let value: u8;
@ -34,7 +39,8 @@ impl Io for Pio<u8> {
value value
} }
/// Write // 写。
/// Write.
#[inline(always)] #[inline(always)]
fn write(&mut self, value: u8) { fn write(&mut self, value: u8) {
unsafe { unsafe {
@ -43,11 +49,13 @@ impl Io for Pio<u8> {
} }
} }
/// Read/Write for word PIO // 逐字端口映射读写。
impl Io for Pio<u16> { /// Read/Write for word PMIO.
impl Io for Pmio<u16> {
type Value = u16; type Value = u16;
/// Read // 读。
/// Read.
#[inline(always)] #[inline(always)]
fn read(&self) -> u16 { fn read(&self) -> u16 {
let value: u16; let value: u16;
@ -57,7 +65,8 @@ impl Io for Pio<u16> {
value value
} }
/// Write // 写。
/// Write.
#[inline(always)] #[inline(always)]
fn write(&mut self, value: u16) { fn write(&mut self, value: u16) {
unsafe { unsafe {
@ -66,11 +75,13 @@ impl Io for Pio<u16> {
} }
} }
/// Read/Write for doubleword PIO // 逐双字端口映射读写。
impl Io for Pio<u32> { /// Read/Write for double-word PMIO.
impl Io for Pmio<u32> {
type Value = u32; type Value = u32;
/// Read // 读。
/// Read.
#[inline(always)] #[inline(always)]
fn read(&self) -> u32 { fn read(&self) -> u32 {
let value: u32; let value: u32;
@ -80,7 +91,8 @@ impl Io for Pio<u32> {
value value
} }
/// Write // 写。
/// Write.
#[inline(always)] #[inline(always)]
fn write(&mut self, value: u32) { fn write(&mut self, value: u32) {
unsafe { unsafe {

View File

@ -38,8 +38,7 @@ impl PlicUnlocked {
let hart_id = cpu_id() as usize; let hart_id = cpu_id() as usize;
let mmio = self let mmio = self
.enable_base .enable_base
.add(PLIC_ENABLE_HART_OFFSET * hart_id) .add(PLIC_ENABLE_HART_OFFSET * hart_id + irq_num / 32);
.add(irq_num / 32);
let mask = 1 << (irq_num % 32); let mask = 1 << (irq_num % 32);
if enable { if enable {
@ -54,8 +53,7 @@ impl PlicUnlocked {
let hart_id = cpu_id() as usize; let hart_id = cpu_id() as usize;
let irq_num = self let irq_num = self
.context_base .context_base
.add(PLIC_CONTEXT_CLAIM_HART_OFFSET * hart_id) .add(PLIC_CONTEXT_CLAIM_HART_OFFSET * hart_id + PLIC_CONTEXT_CLAIM)
.add(PLIC_CONTEXT_CLAIM)
.read() as usize; .read() as usize;
if irq_num == 0 { if irq_num == 0 {
None None
@ -69,8 +67,7 @@ impl PlicUnlocked {
debug_assert!(IRQ_RANGE.contains(&irq_num)); debug_assert!(IRQ_RANGE.contains(&irq_num));
let hart_id = cpu_id() as usize; let hart_id = cpu_id() as usize;
self.context_base self.context_base
.add(PLIC_CONTEXT_CLAIM) .add(PLIC_CONTEXT_CLAIM + PLIC_CONTEXT_CLAIM_HART_OFFSET * hart_id)
.add(PLIC_CONTEXT_CLAIM_HART_OFFSET * hart_id)
.write(irq_num as _); .write(irq_num as _);
} }
@ -84,8 +81,7 @@ impl PlicUnlocked {
fn set_threshold(&mut self, threshold: u8) { fn set_threshold(&mut self, threshold: u8) {
let hart_id = cpu_id() as usize; let hart_id = cpu_id() as usize;
self.context_base self.context_base
.add(PLIC_PRIORITY_HART_OFFSET * hart_id) .add(PLIC_PRIORITY_HART_OFFSET * hart_id + PLIC_CONTEXT_THRESHOLD)
.add(PLIC_CONTEXT_THRESHOLD)
.write(threshold as _); .write(threshold as _);
} }

View File

@ -7,4 +7,4 @@ pub use buffered::BufferedUart;
pub use uart_16550::Uart16550Mmio; pub use uart_16550::Uart16550Mmio;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub use uart_16550::Uart16550Pio; pub use uart_16550::Uart16550Pmio;

View File

@ -201,21 +201,21 @@ impl Uart16550Mmio<u32> {
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
mod pio { mod pmio {
use super::*; use super::*;
use crate::io::Pio; use crate::io::Pmio;
/// PIO driver for UART 16550 /// Pmio driver for UART 16550
pub struct Uart16550Pio { pub struct Uart16550Pmio {
inner: Mutex<Uart16550Inner<Pio<u8>>>, inner: Mutex<Uart16550Inner<Pmio<u8>>>,
listener: EventListener, listener: EventListener,
} }
impl_event_scheme!(Uart16550Pio); impl_event_scheme!(Uart16550Pmio);
impl Scheme for Uart16550Pio { impl Scheme for Uart16550Pmio {
fn name(&self) -> &str { fn name(&self) -> &str {
"uart16550-pio" "uart16550-Pmio"
} }
fn handle_irq(&self, _irq_num: usize) { fn handle_irq(&self, _irq_num: usize) {
@ -223,7 +223,7 @@ mod pio {
} }
} }
impl UartScheme for Uart16550Pio { impl UartScheme for Uart16550Pmio {
fn try_recv(&self) -> DeviceResult<Option<u8>> { fn try_recv(&self) -> DeviceResult<Option<u8>> {
self.inner.lock().try_recv() self.inner.lock().try_recv()
} }
@ -237,17 +237,17 @@ mod pio {
} }
} }
impl Uart16550Pio { impl Uart16550Pmio {
/// Construct a `Uart16550Pio` whose address starts at `base`. /// Construct a `Uart16550Pmio` whose address starts at `base`.
pub fn new(base: u16) -> Self { pub fn new(base: u16) -> Self {
let mut uart = Uart16550Inner::<Pio<u8>> { let mut uart = Uart16550Inner::<Pmio<u8>> {
data: Pio::new(base), data: Pmio::new(base),
int_en: Pio::new(base + 1), int_en: Pmio::new(base + 1),
fifo_ctrl: Pio::new(base + 2), fifo_ctrl: Pmio::new(base + 2),
line_ctrl: Pio::new(base + 3), line_ctrl: Pmio::new(base + 3),
modem_ctrl: Pio::new(base + 4), modem_ctrl: Pmio::new(base + 4),
line_sts: ReadOnly::new(Pio::new(base + 5)), line_sts: ReadOnly::new(Pmio::new(base + 5)),
modem_sts: ReadOnly::new(Pio::new(base + 6)), modem_sts: ReadOnly::new(Pmio::new(base + 6)),
}; };
uart.init(); uart.init();
Self { Self {
@ -259,4 +259,4 @@ mod pio {
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub use pio::Uart16550Pio; pub use pmio::Uart16550Pmio;

View File

@ -26,8 +26,8 @@ hal_fn_impl! {
fn reset() -> ! { fn reset() -> ! {
info!("shutdown..."); info!("shutdown...");
loop { loop {
use zcore_drivers::io::{Io, Pio}; use zcore_drivers::io::{Io, Pmio};
Pio::<u16>::new(0x604).write(0x2000); Pmio::<u16>::new(0x604).write(0x2000);
super::interrupt::wait_for_interrupt(); super::interrupt::wait_for_interrupt();
} }
} }

View File

@ -3,16 +3,16 @@ use alloc::{boxed::Box, sync::Arc};
use zcore_drivers::bus::pci; use zcore_drivers::bus::pci;
use zcore_drivers::irq::x86::Apic; use zcore_drivers::irq::x86::Apic;
use zcore_drivers::scheme::IrqScheme; use zcore_drivers::scheme::IrqScheme;
use zcore_drivers::uart::{BufferedUart, Uart16550Pio}; use zcore_drivers::uart::{BufferedUart, Uart16550Pmio};
use zcore_drivers::{Device, DeviceResult}; use zcore_drivers::{Device, DeviceResult};
use super::trap; use super::trap;
use crate::drivers; use crate::drivers;
pub(super) fn init_early() -> DeviceResult { pub(super) fn init_early() -> DeviceResult {
let uart = Arc::new(Uart16550Pio::new(0x3F8)); let uart = Arc::new(Uart16550Pmio::new(0x3F8));
drivers::add_device(Device::Uart(BufferedUart::new(uart))); drivers::add_device(Device::Uart(BufferedUart::new(uart)));
let uart = Arc::new(Uart16550Pio::new(0x2F8)); let uart = Arc::new(Uart16550Pmio::new(0x2F8));
drivers::add_device(Device::Uart(BufferedUart::new(uart))); drivers::add_device(Device::Uart(BufferedUart::new(uart)));
Ok(()) Ok(())
} }

View File

@ -1,6 +1,6 @@
//! Functions only available on x86 platforms. //! Functions only available on x86 platforms.
pub use zcore_drivers::io::{Io, Pio}; pub use zcore_drivers::io::{Io, Pmio};
/// Get physical address of `acpi_rsdp` and `smbios` on x86_64. /// Get physical address of `acpi_rsdp` and `smbios` on x86_64.
pub fn pc_firmware_tables() -> (u64, u64) { pub fn pc_firmware_tables() -> (u64, u64) {

View File

@ -3,7 +3,7 @@ use super::nodes::{
SharedLegacyIrqHandler, SharedLegacyIrqHandler,
}; };
use super::{ use super::{
config::PciConfig, constants::*, pci_init_args::PciIrqSwizzleLut, pio::pci_bdf_raw_addr, config::PciConfig, constants::*, pci_init_args::PciIrqSwizzleLut, pmio::pci_bdf_raw_addr,
MappedEcamRegion, PciAddrSpace, PciEcamRegion, MappedEcamRegion, PciAddrSpace, PciEcamRegion,
}; };
use crate::dev::Interrupt; use crate::dev::Interrupt;
@ -447,9 +447,9 @@ impl PCIeAddressProvider for MmioPcieAddressProvider {
/// Systems that have PIO mapped Config Spaces. /// Systems that have PIO mapped Config Spaces.
#[derive(Default)] #[derive(Default)]
pub struct PioPcieAddressProvider; pub struct PmioPcieAddressProvider;
impl PCIeAddressProvider for PioPcieAddressProvider { impl PCIeAddressProvider for PmioPcieAddressProvider {
fn create_config(&self, addr: u64) -> Arc<PciConfig> { fn create_config(&self, addr: u64) -> Arc<PciConfig> {
Arc::new(PciConfig { Arc::new(PciConfig {
addr_space: PciAddrSpace::PIO, addr_space: PciAddrSpace::PIO,

View File

@ -1,4 +1,4 @@
use super::pio::{pio_config_read_addr, pio_config_write_addr}; use super::pmio::{pmio_config_read_addr, pmio_config_write_addr};
use super::PciAddrSpace; use super::PciAddrSpace;
use numeric_enum_macro::numeric_enum; use numeric_enum_macro::numeric_enum;
@ -14,21 +14,21 @@ impl PciConfig {
trace!("read8 @ {:#x?}", offset); trace!("read8 @ {:#x?}", offset);
match self.addr_space { match self.addr_space {
PciAddrSpace::MMIO => unsafe { u8::from_le(*(offset as *const u8)) }, PciAddrSpace::MMIO => unsafe { u8::from_le(*(offset as *const u8)) },
PciAddrSpace::PIO => pio_config_read_addr(offset as u32, 8).unwrap() as u8, PciAddrSpace::PIO => pmio_config_read_addr(offset as u32, 8).unwrap() as u8,
} }
} }
pub fn read16_offset(&self, addr: usize) -> u16 { pub fn read16_offset(&self, addr: usize) -> u16 {
trace!("read16 @ {:#x?}", addr); trace!("read16 @ {:#x?}", addr);
match self.addr_space { match self.addr_space {
PciAddrSpace::MMIO => unsafe { u16::from_le(*(addr as *const u16)) }, PciAddrSpace::MMIO => unsafe { u16::from_le(*(addr as *const u16)) },
PciAddrSpace::PIO => pio_config_read_addr(addr as u32, 16).unwrap() as u16, PciAddrSpace::PIO => pmio_config_read_addr(addr as u32, 16).unwrap() as u16,
} }
} }
pub fn read32_offset(&self, addr: usize) -> u32 { pub fn read32_offset(&self, addr: usize) -> u32 {
trace!("read32 @ {:#x?}", addr); trace!("read32 @ {:#x?}", addr);
match self.addr_space { match self.addr_space {
PciAddrSpace::MMIO => unsafe { u32::from_le(*(addr as *const u32)) }, PciAddrSpace::MMIO => unsafe { u32::from_le(*(addr as *const u32)) },
PciAddrSpace::PIO => pio_config_read_addr(addr as u32, 32).unwrap(), PciAddrSpace::PIO => pmio_config_read_addr(addr as u32, 32).unwrap(),
} }
} }
pub fn read8(&self, addr: PciReg8) -> u8 { pub fn read8(&self, addr: PciReg8) -> u8 {
@ -56,7 +56,7 @@ impl PciConfig {
pub fn write8_offset(&self, addr: usize, val: u8) { pub fn write8_offset(&self, addr: usize, val: u8) {
match self.addr_space { match self.addr_space {
PciAddrSpace::MMIO => unsafe { *(addr as *mut u8) = val }, PciAddrSpace::MMIO => unsafe { *(addr as *mut u8) = val },
PciAddrSpace::PIO => pio_config_write_addr(addr as u32, val as u32, 8).unwrap(), PciAddrSpace::PIO => pmio_config_write_addr(addr as u32, val as u32, 8).unwrap(),
} }
} }
pub fn write16_offset(&self, addr: usize, val: u16) { pub fn write16_offset(&self, addr: usize, val: u16) {
@ -67,13 +67,13 @@ impl PciConfig {
); );
match self.addr_space { match self.addr_space {
PciAddrSpace::MMIO => unsafe { *(addr as *mut u16) = val }, PciAddrSpace::MMIO => unsafe { *(addr as *mut u16) = val },
PciAddrSpace::PIO => pio_config_write_addr(addr as u32, val as u32, 16).unwrap(), PciAddrSpace::PIO => pmio_config_write_addr(addr as u32, val as u32, 16).unwrap(),
} }
} }
pub fn write32_offset(&self, addr: usize, val: u32) { pub fn write32_offset(&self, addr: usize, val: u32) {
match self.addr_space { match self.addr_space {
PciAddrSpace::MMIO => unsafe { *(addr as *mut u32) = val }, PciAddrSpace::MMIO => unsafe { *(addr as *mut u32) = val },
PciAddrSpace::PIO => pio_config_write_addr(addr as u32, val as u32, 32).unwrap(), PciAddrSpace::PIO => pmio_config_write_addr(addr as u32, val as u32, 32).unwrap(),
} }
} }
pub fn write8(&self, addr: PciReg8, val: u8) { pub fn write8(&self, addr: PciReg8, val: u8) {

View File

@ -5,14 +5,14 @@ mod caps;
mod config; mod config;
mod nodes; mod nodes;
pub mod pci_init_args; pub mod pci_init_args;
mod pio; mod pmio;
pub use self::bus::{ pub use self::bus::{
MmioPcieAddressProvider, PCIeBusDriver, PcieDeviceInfo, PcieDeviceKObject, MmioPcieAddressProvider, PCIeBusDriver, PcieDeviceInfo, PcieDeviceKObject,
PioPcieAddressProvider, PmioPcieAddressProvider,
}; };
pub use self::nodes::{IPciNode, PcieIrqMode}; pub use self::nodes::{IPciNode, PcieIrqMode};
pub use self::pio::{pio_config_read, pio_config_write}; pub use self::pmio::{pio_config_read, pio_config_write};
/// Type of PCI address space. /// Type of PCI address space.
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]

View File

@ -12,7 +12,7 @@ pub fn pci_bdf_raw_addr(bus: u8, dev: u8, func: u8, offset: u8) -> u32 {
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(all(target_arch = "x86_64", target_os = "none"))] { if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
use kernel_hal::x86_64::{Io, Pio}; use kernel_hal::x86_64::{Io, Pmio};
use spin::Mutex; use spin::Mutex;
static PIO_LOCK: Mutex<()> = Mutex::new(()); static PIO_LOCK: Mutex<()> = Mutex::new(());
@ -20,9 +20,9 @@ if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
const PCI_CONFIG_DATA: u16 = 0xcfc; const PCI_CONFIG_DATA: u16 = 0xcfc;
const PCI_CONFIG_ENABLE: u32 = 1 << 31; const PCI_CONFIG_ENABLE: u32 = 1 << 31;
pub fn pio_config_read_addr(addr: u32, width: usize) -> ZxResult<u32> { pub fn pmio_config_read_addr(addr: u32, width: usize) -> ZxResult<u32> {
let mut port_cfg = Pio::<u32>::new(PCI_CONFIG_ADDR); let mut port_cfg = Pmio::<u32>::new(PCI_CONFIG_ADDR);
let port_data = Pio::<u32>::new(PCI_CONFIG_DATA); let port_data = Pmio::<u32>::new(PCI_CONFIG_DATA);
let _lock = PIO_LOCK.lock(); let _lock = PIO_LOCK.lock();
let shift = ((addr & 0x3) << 3) as usize; let shift = ((addr & 0x3) << 3) as usize;
@ -33,9 +33,9 @@ if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
let tmp_val = u32::from_le(port_data.read()); let tmp_val = u32::from_le(port_data.read());
Ok((tmp_val >> shift) & (((1u64 << width) - 1) as u32)) Ok((tmp_val >> shift) & (((1u64 << width) - 1) as u32))
} }
pub fn pio_config_write_addr(addr: u32, val: u32, width: usize) -> ZxResult { pub fn pmio_config_write_addr(addr: u32, val: u32, width: usize) -> ZxResult {
let mut port_cfg = Pio::<u32>::new(PCI_CONFIG_ADDR); let mut port_cfg = Pmio::<u32>::new(PCI_CONFIG_ADDR);
let mut port_data = Pio::<u32>::new(PCI_CONFIG_DATA); let mut port_data = Pmio::<u32>::new(PCI_CONFIG_DATA);
let _lock = PIO_LOCK.lock(); let _lock = PIO_LOCK.lock();
let shift = ((addr & 0x3) << 3) as usize; let shift = ((addr & 0x3) << 3) as usize;
@ -54,17 +54,17 @@ if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
Ok(()) Ok(())
} }
} else { } else {
pub fn pio_config_read_addr(_addr: u32, _width: usize) -> ZxResult<u32> { pub fn pmio_config_read_addr(_addr: u32, _width: usize) -> ZxResult<u32> {
Err(ZxError::NOT_SUPPORTED) Err(ZxError::NOT_SUPPORTED)
} }
pub fn pio_config_write_addr(_addr: u32, _val: u32, _width: usize) -> ZxResult { pub fn pmio_config_write_addr(_addr: u32, _val: u32, _width: usize) -> ZxResult {
Err(ZxError::NOT_SUPPORTED) Err(ZxError::NOT_SUPPORTED)
} }
} }
} // cfg_if! } // cfg_if!
pub fn pio_config_read(bus: u8, dev: u8, func: u8, offset: u8, width: usize) -> ZxResult<u32> { 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) pmio_config_read_addr(pci_bdf_raw_addr(bus, dev, func, offset), width)
} }
pub fn pio_config_write( pub fn pio_config_write(
@ -75,5 +75,5 @@ pub fn pio_config_write(
val: u32, val: u32,
width: usize, width: usize,
) -> ZxResult { ) -> ZxResult {
pio_config_write_addr(pci_bdf_raw_addr(bus, dev, func, offset), val, width) pmio_config_write_addr(pci_bdf_raw_addr(bus, dev, func, offset), val, width)
} }

View File

@ -6,7 +6,7 @@ use zircon_object::{
constants::*, constants::*,
pci_init_args::{PciInitArgsAddrWindows, PciInitArgsHeader, PCI_INIT_ARG_MAX_SIZE}, pci_init_args::{PciInitArgsAddrWindows, PciInitArgsHeader, PCI_INIT_ARG_MAX_SIZE},
MmioPcieAddressProvider, PCIeBusDriver, PciAddrSpace, PciEcamRegion, PcieDeviceInfo, MmioPcieAddressProvider, PCIeBusDriver, PciAddrSpace, PciEcamRegion, PcieDeviceInfo,
PcieDeviceKObject, PcieIrqMode, PioPcieAddressProvider, PcieDeviceKObject, PcieIrqMode, PmioPcieAddressProvider,
}, },
dev::{Resource, ResourceKind}, dev::{Resource, ResourceKind},
vm::{pages, VmObject}, vm::{pages, VmObject},
@ -143,7 +143,7 @@ impl Syscall<'_> {
})?; })?;
PCIeBusDriver::set_address_translation_provider(addr_provider)?; PCIeBusDriver::set_address_translation_provider(addr_provider)?;
} else if addr_win.cfg_space_type == PCI_CFG_SPACE_TYPE_PIO { } else if addr_win.cfg_space_type == PCI_CFG_SPACE_TYPE_PIO {
let addr_provider = Arc::new(PioPcieAddressProvider::default()); let addr_provider = Arc::new(PmioPcieAddressProvider::default());
PCIeBusDriver::set_address_translation_provider(addr_provider)?; PCIeBusDriver::set_address_translation_provider(addr_provider)?;
} else { } else {
return Err(ZxError::INVALID_ARGS); return Err(ZxError::INVALID_ARGS);