forked from rcore-os/zCore
refactor(drivers): 修改 io
- 根据 wikipedia,pio 改名 pmio - 为 mmio 读写增加内存屏障 - 为 io 补充文档
This commit is contained in:
parent
fcc46ebfc5
commit
99f21ba488
|
@ -1,12 +1,10 @@
|
|||
use core::mem::MaybeUninit;
|
||||
use super::Io;
|
||||
use core::ops::{BitAnd, BitOr, Not};
|
||||
|
||||
use super::Io;
|
||||
|
||||
// 主存映射 I/O。
|
||||
/// Memory-mapped I/O.
|
||||
#[repr(transparent)]
|
||||
pub struct Mmio<T> {
|
||||
value: MaybeUninit<T>,
|
||||
}
|
||||
pub struct Mmio<T>(T);
|
||||
|
||||
impl<T> Mmio<T> {
|
||||
/// # Safety
|
||||
|
@ -25,9 +23,7 @@ impl<T> Mmio<T> {
|
|||
}
|
||||
|
||||
pub fn add<'a>(&self, offset: usize) -> &'a mut Self {
|
||||
unsafe {
|
||||
Self::from_base(self.value.as_ptr() as usize + offset * core::mem::size_of::<T>())
|
||||
}
|
||||
unsafe { Self::from_base((&self.0 as *const T).add(offset) as _) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,10 +34,19 @@ where
|
|||
type Value = 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) {
|
||||
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)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
||||
mod mmio;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod pio;
|
||||
mod pmio;
|
||||
|
||||
pub use mmio::Mmio;
|
||||
#[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 {
|
||||
// 可访问的对象的类型。
|
||||
/// The type of object to access.
|
||||
type Value: Copy
|
||||
+ BitAnd<Output = Self::Value>
|
||||
+ BitOr<Output = Self::Value>
|
||||
+ Not<Output = Self::Value>;
|
||||
|
||||
// 从外设读取值。
|
||||
/// Reads value from device.
|
||||
fn read(&self) -> Self::Value;
|
||||
|
||||
// 向外设写入值。
|
||||
/// Writes `value` to device.
|
||||
fn write(&mut self, value: Self::Value);
|
||||
}
|
||||
|
||||
// 外设地址空间的一个只读单元。
|
||||
/// A readonly unit in device address space.
|
||||
#[repr(transparent)]
|
||||
pub struct ReadOnly<I> {
|
||||
inner: I,
|
||||
}
|
||||
pub struct ReadOnly<I>(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> {
|
||||
// 从外设读取值。
|
||||
/// Reads value from device.
|
||||
#[inline(always)]
|
||||
pub fn read(&self) -> I::Value {
|
||||
self.inner.read()
|
||||
self.0.read()
|
||||
}
|
||||
}
|
||||
|
||||
// 外设地址空间的一个只写单元。
|
||||
/// A write-only unit in device address space.
|
||||
#[repr(transparent)]
|
||||
pub struct WriteOnly<I> {
|
||||
inner: I,
|
||||
}
|
||||
pub struct WriteOnly<I>(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> {
|
||||
// 向外设写入值。
|
||||
/// Writes `value` to device.
|
||||
#[inline(always)]
|
||||
pub fn write(&mut self, value: I::Value) {
|
||||
self.inner.write(value)
|
||||
self.0.write(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,35 @@
|
|||
use core::arch::asm;
|
||||
use core::marker::PhantomData;
|
||||
// 端口映射 I/O。
|
||||
//! Port-mapped I/O.
|
||||
|
||||
use super::Io;
|
||||
use core::{arch::asm, marker::PhantomData};
|
||||
|
||||
/// Generic PIO
|
||||
// 端口映射 I/O。
|
||||
/// Port-mapped I/O.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Pio<T> {
|
||||
pub struct Pmio<T> {
|
||||
port: u16,
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> Pio<T> {
|
||||
/// Create a PIO from a given port
|
||||
impl<T> Pmio<T> {
|
||||
// 映射指定端口进行外设访问。
|
||||
/// Maps a given port to assess device.
|
||||
pub const fn new(port: u16) -> Self {
|
||||
Pio::<T> {
|
||||
Self {
|
||||
port,
|
||||
_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;
|
||||
|
||||
/// Read
|
||||
// 读。
|
||||
/// Read.
|
||||
#[inline(always)]
|
||||
fn read(&self) -> u8 {
|
||||
let value: u8;
|
||||
|
@ -34,7 +39,8 @@ impl Io for Pio<u8> {
|
|||
value
|
||||
}
|
||||
|
||||
/// Write
|
||||
// 写。
|
||||
/// Write.
|
||||
#[inline(always)]
|
||||
fn write(&mut self, value: u8) {
|
||||
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;
|
||||
|
||||
/// Read
|
||||
// 读。
|
||||
/// Read.
|
||||
#[inline(always)]
|
||||
fn read(&self) -> u16 {
|
||||
let value: u16;
|
||||
|
@ -57,7 +65,8 @@ impl Io for Pio<u16> {
|
|||
value
|
||||
}
|
||||
|
||||
/// Write
|
||||
// 写。
|
||||
/// Write.
|
||||
#[inline(always)]
|
||||
fn write(&mut self, value: u16) {
|
||||
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;
|
||||
|
||||
/// Read
|
||||
// 读。
|
||||
/// Read.
|
||||
#[inline(always)]
|
||||
fn read(&self) -> u32 {
|
||||
let value: u32;
|
||||
|
@ -80,7 +91,8 @@ impl Io for Pio<u32> {
|
|||
value
|
||||
}
|
||||
|
||||
/// Write
|
||||
// 写。
|
||||
/// Write.
|
||||
#[inline(always)]
|
||||
fn write(&mut self, value: u32) {
|
||||
unsafe {
|
|
@ -38,8 +38,7 @@ impl PlicUnlocked {
|
|||
let hart_id = cpu_id() as usize;
|
||||
let mmio = self
|
||||
.enable_base
|
||||
.add(PLIC_ENABLE_HART_OFFSET * hart_id)
|
||||
.add(irq_num / 32);
|
||||
.add(PLIC_ENABLE_HART_OFFSET * hart_id + irq_num / 32);
|
||||
|
||||
let mask = 1 << (irq_num % 32);
|
||||
if enable {
|
||||
|
@ -54,8 +53,7 @@ impl PlicUnlocked {
|
|||
let hart_id = cpu_id() as usize;
|
||||
let irq_num = self
|
||||
.context_base
|
||||
.add(PLIC_CONTEXT_CLAIM_HART_OFFSET * hart_id)
|
||||
.add(PLIC_CONTEXT_CLAIM)
|
||||
.add(PLIC_CONTEXT_CLAIM_HART_OFFSET * hart_id + PLIC_CONTEXT_CLAIM)
|
||||
.read() as usize;
|
||||
if irq_num == 0 {
|
||||
None
|
||||
|
@ -69,8 +67,7 @@ impl PlicUnlocked {
|
|||
debug_assert!(IRQ_RANGE.contains(&irq_num));
|
||||
let hart_id = cpu_id() as usize;
|
||||
self.context_base
|
||||
.add(PLIC_CONTEXT_CLAIM)
|
||||
.add(PLIC_CONTEXT_CLAIM_HART_OFFSET * hart_id)
|
||||
.add(PLIC_CONTEXT_CLAIM + PLIC_CONTEXT_CLAIM_HART_OFFSET * hart_id)
|
||||
.write(irq_num as _);
|
||||
}
|
||||
|
||||
|
@ -84,8 +81,7 @@ impl PlicUnlocked {
|
|||
fn set_threshold(&mut self, threshold: u8) {
|
||||
let hart_id = cpu_id() as usize;
|
||||
self.context_base
|
||||
.add(PLIC_PRIORITY_HART_OFFSET * hart_id)
|
||||
.add(PLIC_CONTEXT_THRESHOLD)
|
||||
.add(PLIC_PRIORITY_HART_OFFSET * hart_id + PLIC_CONTEXT_THRESHOLD)
|
||||
.write(threshold as _);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,4 +7,4 @@ pub use buffered::BufferedUart;
|
|||
pub use uart_16550::Uart16550Mmio;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub use uart_16550::Uart16550Pio;
|
||||
pub use uart_16550::Uart16550Pmio;
|
||||
|
|
|
@ -201,21 +201,21 @@ impl Uart16550Mmio<u32> {
|
|||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod pio {
|
||||
mod pmio {
|
||||
use super::*;
|
||||
use crate::io::Pio;
|
||||
use crate::io::Pmio;
|
||||
|
||||
/// PIO driver for UART 16550
|
||||
pub struct Uart16550Pio {
|
||||
inner: Mutex<Uart16550Inner<Pio<u8>>>,
|
||||
/// Pmio driver for UART 16550
|
||||
pub struct Uart16550Pmio {
|
||||
inner: Mutex<Uart16550Inner<Pmio<u8>>>,
|
||||
listener: EventListener,
|
||||
}
|
||||
|
||||
impl_event_scheme!(Uart16550Pio);
|
||||
impl_event_scheme!(Uart16550Pmio);
|
||||
|
||||
impl Scheme for Uart16550Pio {
|
||||
impl Scheme for Uart16550Pmio {
|
||||
fn name(&self) -> &str {
|
||||
"uart16550-pio"
|
||||
"uart16550-Pmio"
|
||||
}
|
||||
|
||||
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>> {
|
||||
self.inner.lock().try_recv()
|
||||
}
|
||||
|
@ -237,17 +237,17 @@ mod pio {
|
|||
}
|
||||
}
|
||||
|
||||
impl Uart16550Pio {
|
||||
/// Construct a `Uart16550Pio` whose address starts at `base`.
|
||||
impl Uart16550Pmio {
|
||||
/// Construct a `Uart16550Pmio` whose address starts at `base`.
|
||||
pub fn new(base: u16) -> Self {
|
||||
let mut uart = Uart16550Inner::<Pio<u8>> {
|
||||
data: Pio::new(base),
|
||||
int_en: Pio::new(base + 1),
|
||||
fifo_ctrl: Pio::new(base + 2),
|
||||
line_ctrl: Pio::new(base + 3),
|
||||
modem_ctrl: Pio::new(base + 4),
|
||||
line_sts: ReadOnly::new(Pio::new(base + 5)),
|
||||
modem_sts: ReadOnly::new(Pio::new(base + 6)),
|
||||
let mut uart = Uart16550Inner::<Pmio<u8>> {
|
||||
data: Pmio::new(base),
|
||||
int_en: Pmio::new(base + 1),
|
||||
fifo_ctrl: Pmio::new(base + 2),
|
||||
line_ctrl: Pmio::new(base + 3),
|
||||
modem_ctrl: Pmio::new(base + 4),
|
||||
line_sts: ReadOnly::new(Pmio::new(base + 5)),
|
||||
modem_sts: ReadOnly::new(Pmio::new(base + 6)),
|
||||
};
|
||||
uart.init();
|
||||
Self {
|
||||
|
@ -259,4 +259,4 @@ mod pio {
|
|||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub use pio::Uart16550Pio;
|
||||
pub use pmio::Uart16550Pmio;
|
||||
|
|
|
@ -26,8 +26,8 @@ hal_fn_impl! {
|
|||
fn reset() -> ! {
|
||||
info!("shutdown...");
|
||||
loop {
|
||||
use zcore_drivers::io::{Io, Pio};
|
||||
Pio::<u16>::new(0x604).write(0x2000);
|
||||
use zcore_drivers::io::{Io, Pmio};
|
||||
Pmio::<u16>::new(0x604).write(0x2000);
|
||||
super::interrupt::wait_for_interrupt();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,16 +3,16 @@ use alloc::{boxed::Box, sync::Arc};
|
|||
use zcore_drivers::bus::pci;
|
||||
use zcore_drivers::irq::x86::Apic;
|
||||
use zcore_drivers::scheme::IrqScheme;
|
||||
use zcore_drivers::uart::{BufferedUart, Uart16550Pio};
|
||||
use zcore_drivers::uart::{BufferedUart, Uart16550Pmio};
|
||||
use zcore_drivers::{Device, DeviceResult};
|
||||
|
||||
use super::trap;
|
||||
use crate::drivers;
|
||||
|
||||
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)));
|
||||
let uart = Arc::new(Uart16550Pio::new(0x2F8));
|
||||
let uart = Arc::new(Uart16550Pmio::new(0x2F8));
|
||||
drivers::add_device(Device::Uart(BufferedUart::new(uart)));
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! 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.
|
||||
pub fn pc_firmware_tables() -> (u64, u64) {
|
||||
|
|
|
@ -3,7 +3,7 @@ use super::nodes::{
|
|||
SharedLegacyIrqHandler,
|
||||
};
|
||||
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,
|
||||
};
|
||||
use crate::dev::Interrupt;
|
||||
|
@ -447,9 +447,9 @@ impl PCIeAddressProvider for MmioPcieAddressProvider {
|
|||
|
||||
/// Systems that have PIO mapped Config Spaces.
|
||||
#[derive(Default)]
|
||||
pub struct PioPcieAddressProvider;
|
||||
pub struct PmioPcieAddressProvider;
|
||||
|
||||
impl PCIeAddressProvider for PioPcieAddressProvider {
|
||||
impl PCIeAddressProvider for PmioPcieAddressProvider {
|
||||
fn create_config(&self, addr: u64) -> Arc<PciConfig> {
|
||||
Arc::new(PciConfig {
|
||||
addr_space: PciAddrSpace::PIO,
|
||||
|
|
|
@ -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 numeric_enum_macro::numeric_enum;
|
||||
|
||||
|
@ -14,21 +14,21 @@ impl PciConfig {
|
|||
trace!("read8 @ {:#x?}", offset);
|
||||
match self.addr_space {
|
||||
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 {
|
||||
trace!("read16 @ {:#x?}", addr);
|
||||
match self.addr_space {
|
||||
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 {
|
||||
trace!("read32 @ {:#x?}", addr);
|
||||
match self.addr_space {
|
||||
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 {
|
||||
|
@ -56,7 +56,7 @@ impl PciConfig {
|
|||
pub fn write8_offset(&self, addr: usize, val: u8) {
|
||||
match self.addr_space {
|
||||
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) {
|
||||
|
@ -67,13 +67,13 @@ impl PciConfig {
|
|||
);
|
||||
match self.addr_space {
|
||||
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) {
|
||||
match self.addr_space {
|
||||
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) {
|
||||
|
|
|
@ -5,14 +5,14 @@ mod caps;
|
|||
mod config;
|
||||
mod nodes;
|
||||
pub mod pci_init_args;
|
||||
mod pio;
|
||||
mod pmio;
|
||||
|
||||
pub use self::bus::{
|
||||
MmioPcieAddressProvider, PCIeBusDriver, PcieDeviceInfo, PcieDeviceKObject,
|
||||
PioPcieAddressProvider,
|
||||
PmioPcieAddressProvider,
|
||||
};
|
||||
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.
|
||||
#[derive(PartialEq, Debug)]
|
||||
|
|
|
@ -12,7 +12,7 @@ pub fn pci_bdf_raw_addr(bus: u8, dev: u8, func: u8, offset: u8) -> u32 {
|
|||
|
||||
cfg_if::cfg_if! {
|
||||
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;
|
||||
|
||||
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_ENABLE: u32 = 1 << 31;
|
||||
|
||||
pub fn pio_config_read_addr(addr: u32, width: usize) -> ZxResult<u32> {
|
||||
let mut port_cfg = Pio::<u32>::new(PCI_CONFIG_ADDR);
|
||||
let port_data = Pio::<u32>::new(PCI_CONFIG_DATA);
|
||||
pub fn pmio_config_read_addr(addr: u32, width: usize) -> ZxResult<u32> {
|
||||
let mut port_cfg = Pmio::<u32>::new(PCI_CONFIG_ADDR);
|
||||
let port_data = Pmio::<u32>::new(PCI_CONFIG_DATA);
|
||||
|
||||
let _lock = PIO_LOCK.lock();
|
||||
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());
|
||||
Ok((tmp_val >> shift) & (((1u64 << width) - 1) as u32))
|
||||
}
|
||||
pub fn pio_config_write_addr(addr: u32, val: u32, width: usize) -> ZxResult {
|
||||
let mut port_cfg = Pio::<u32>::new(PCI_CONFIG_ADDR);
|
||||
let mut port_data = Pio::<u32>::new(PCI_CONFIG_DATA);
|
||||
pub fn pmio_config_write_addr(addr: u32, val: u32, width: usize) -> ZxResult {
|
||||
let mut port_cfg = Pmio::<u32>::new(PCI_CONFIG_ADDR);
|
||||
let mut port_data = Pmio::<u32>::new(PCI_CONFIG_DATA);
|
||||
|
||||
let _lock = PIO_LOCK.lock();
|
||||
let shift = ((addr & 0x3) << 3) as usize;
|
||||
|
@ -54,17 +54,17 @@ if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
|
|||
Ok(())
|
||||
}
|
||||
} 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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
} // 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)
|
||||
pmio_config_read_addr(pci_bdf_raw_addr(bus, dev, func, offset), width)
|
||||
}
|
||||
|
||||
pub fn pio_config_write(
|
||||
|
@ -75,5 +75,5 @@ pub fn pio_config_write(
|
|||
val: u32,
|
||||
width: usize,
|
||||
) -> 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)
|
||||
}
|
|
@ -6,7 +6,7 @@ use zircon_object::{
|
|||
constants::*,
|
||||
pci_init_args::{PciInitArgsAddrWindows, PciInitArgsHeader, PCI_INIT_ARG_MAX_SIZE},
|
||||
MmioPcieAddressProvider, PCIeBusDriver, PciAddrSpace, PciEcamRegion, PcieDeviceInfo,
|
||||
PcieDeviceKObject, PcieIrqMode, PioPcieAddressProvider,
|
||||
PcieDeviceKObject, PcieIrqMode, PmioPcieAddressProvider,
|
||||
},
|
||||
dev::{Resource, ResourceKind},
|
||||
vm::{pages, VmObject},
|
||||
|
@ -143,7 +143,7 @@ impl Syscall<'_> {
|
|||
})?;
|
||||
PCIeBusDriver::set_address_translation_provider(addr_provider)?;
|
||||
} 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)?;
|
||||
} else {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
|
|
Loading…
Reference in New Issue