diff --git a/drivers/src/io/mmio.rs b/drivers/src/io/mmio.rs index 32bc81f5..dde61f0b 100644 --- a/drivers/src/io/mmio.rs +++ b/drivers/src/io/mmio.rs @@ -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 { - value: MaybeUninit, -} +pub struct Mmio(T); impl Mmio { /// # Safety @@ -25,9 +23,7 @@ impl Mmio { } 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::()) - } + 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) + }; } } diff --git a/drivers/src/io/mod.rs b/drivers/src/io/mod.rs index 99a5ff31..4afcc0fe 100644 --- a/drivers/src/io/mod.rs +++ b/drivers/src/io/mod.rs @@ -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 + BitOr + Not; + // 从外设读取值。 + /// 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 { - inner: I, -} +pub struct ReadOnly(I); impl ReadOnly { - pub const fn new(inner: I) -> ReadOnly { - ReadOnly { inner } + // 构造外设地址空间的一个只读单元。 + /// Constructs a readonly unit in device address space. + pub const fn new(inner: I) -> Self { + Self(inner) } } impl ReadOnly { + // 从外设读取值。 + /// 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 { - inner: I, -} +pub struct WriteOnly(I); impl WriteOnly { - pub const fn new(inner: I) -> WriteOnly { - WriteOnly { inner } + // 构造外设地址空间的一个只写单元。 + /// Constructs a write-only unit in device address space. + pub const fn new(inner: I) -> Self { + Self(inner) } } impl WriteOnly { + // 向外设写入值。 + /// Writes `value` to device. #[inline(always)] pub fn write(&mut self, value: I::Value) { - self.inner.write(value) + self.0.write(value); } } diff --git a/drivers/src/io/pio.rs b/drivers/src/io/pmio.rs similarity index 68% rename from drivers/src/io/pio.rs rename to drivers/src/io/pmio.rs index 47fa8f86..e3e9a0cf 100644 --- a/drivers/src/io/pio.rs +++ b/drivers/src/io/pmio.rs @@ -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 { +pub struct Pmio { port: u16, _phantom: PhantomData, } -impl Pio { - /// Create a PIO from a given port +impl Pmio { + // 映射指定端口进行外设访问。 + /// Maps a given port to assess device. pub const fn new(port: u16) -> Self { - Pio:: { + Self { port, _phantom: PhantomData, } } } -/// Read/Write for byte PIO -impl Io for Pio { +// 逐字节端口映射读写。 +/// Read/Write for byte PMIO. +impl Io for Pmio { type Value = u8; - /// Read + // 读。 + /// Read. #[inline(always)] fn read(&self) -> u8 { let value: u8; @@ -34,7 +39,8 @@ impl Io for Pio { value } - /// Write + // 写。 + /// Write. #[inline(always)] fn write(&mut self, value: u8) { unsafe { @@ -43,11 +49,13 @@ impl Io for Pio { } } -/// Read/Write for word PIO -impl Io for Pio { +// 逐字端口映射读写。 +/// Read/Write for word PMIO. +impl Io for Pmio { type Value = u16; - /// Read + // 读。 + /// Read. #[inline(always)] fn read(&self) -> u16 { let value: u16; @@ -57,7 +65,8 @@ impl Io for Pio { value } - /// Write + // 写。 + /// Write. #[inline(always)] fn write(&mut self, value: u16) { unsafe { @@ -66,11 +75,13 @@ impl Io for Pio { } } -/// Read/Write for doubleword PIO -impl Io for Pio { +// 逐双字端口映射读写。 +/// Read/Write for double-word PMIO. +impl Io for Pmio { type Value = u32; - /// Read + // 读。 + /// Read. #[inline(always)] fn read(&self) -> u32 { let value: u32; @@ -80,7 +91,8 @@ impl Io for Pio { value } - /// Write + // 写。 + /// Write. #[inline(always)] fn write(&mut self, value: u32) { unsafe { diff --git a/drivers/src/irq/riscv_plic.rs b/drivers/src/irq/riscv_plic.rs index 42f3999e..8933de4f 100644 --- a/drivers/src/irq/riscv_plic.rs +++ b/drivers/src/irq/riscv_plic.rs @@ -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 _); } diff --git a/drivers/src/uart/mod.rs b/drivers/src/uart/mod.rs index 52f8cb94..a805b0d3 100644 --- a/drivers/src/uart/mod.rs +++ b/drivers/src/uart/mod.rs @@ -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; diff --git a/drivers/src/uart/uart_16550.rs b/drivers/src/uart/uart_16550.rs index 9061d9d5..2662715e 100644 --- a/drivers/src/uart/uart_16550.rs +++ b/drivers/src/uart/uart_16550.rs @@ -201,21 +201,21 @@ impl Uart16550Mmio { } #[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>>, + /// Pmio driver for UART 16550 + pub struct Uart16550Pmio { + inner: Mutex>>, 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> { 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::> { - 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::> { + 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; diff --git a/kernel-hal/src/bare/arch/x86_64/cpu.rs b/kernel-hal/src/bare/arch/x86_64/cpu.rs index 2ccd3abd..5d802d96 100644 --- a/kernel-hal/src/bare/arch/x86_64/cpu.rs +++ b/kernel-hal/src/bare/arch/x86_64/cpu.rs @@ -26,8 +26,8 @@ hal_fn_impl! { fn reset() -> ! { info!("shutdown..."); loop { - use zcore_drivers::io::{Io, Pio}; - Pio::::new(0x604).write(0x2000); + use zcore_drivers::io::{Io, Pmio}; + Pmio::::new(0x604).write(0x2000); super::interrupt::wait_for_interrupt(); } } diff --git a/kernel-hal/src/bare/arch/x86_64/drivers.rs b/kernel-hal/src/bare/arch/x86_64/drivers.rs index aefcd7bc..e8b1834a 100644 --- a/kernel-hal/src/bare/arch/x86_64/drivers.rs +++ b/kernel-hal/src/bare/arch/x86_64/drivers.rs @@ -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(()) } diff --git a/kernel-hal/src/bare/arch/x86_64/special.rs b/kernel-hal/src/bare/arch/x86_64/special.rs index c472fb8e..d41faf1f 100644 --- a/kernel-hal/src/bare/arch/x86_64/special.rs +++ b/kernel-hal/src/bare/arch/x86_64/special.rs @@ -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) { diff --git a/zircon-object/src/dev/pci/bus.rs b/zircon-object/src/dev/pci/bus.rs index f7239ebc..56054ef4 100644 --- a/zircon-object/src/dev/pci/bus.rs +++ b/zircon-object/src/dev/pci/bus.rs @@ -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 { Arc::new(PciConfig { addr_space: PciAddrSpace::PIO, diff --git a/zircon-object/src/dev/pci/config.rs b/zircon-object/src/dev/pci/config.rs index af08a9d3..7f70ad1b 100644 --- a/zircon-object/src/dev/pci/config.rs +++ b/zircon-object/src/dev/pci/config.rs @@ -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) { diff --git a/zircon-object/src/dev/pci/mod.rs b/zircon-object/src/dev/pci/mod.rs index 82ae6641..27c8132c 100644 --- a/zircon-object/src/dev/pci/mod.rs +++ b/zircon-object/src/dev/pci/mod.rs @@ -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)] diff --git a/zircon-object/src/dev/pci/pio.rs b/zircon-object/src/dev/pci/pmio.rs similarity index 72% rename from zircon-object/src/dev/pci/pio.rs rename to zircon-object/src/dev/pci/pmio.rs index 73d03076..4c023a1f 100644 --- a/zircon-object/src/dev/pci/pio.rs +++ b/zircon-object/src/dev/pci/pmio.rs @@ -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 { - let mut port_cfg = Pio::::new(PCI_CONFIG_ADDR); - let port_data = Pio::::new(PCI_CONFIG_DATA); + pub fn pmio_config_read_addr(addr: u32, width: usize) -> ZxResult { + let mut port_cfg = Pmio::::new(PCI_CONFIG_ADDR); + let port_data = Pmio::::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::::new(PCI_CONFIG_ADDR); - let mut port_data = Pio::::new(PCI_CONFIG_DATA); + pub fn pmio_config_write_addr(addr: u32, val: u32, width: usize) -> ZxResult { + let mut port_cfg = Pmio::::new(PCI_CONFIG_ADDR); + let mut port_data = Pmio::::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 { + pub fn pmio_config_read_addr(_addr: u32, _width: usize) -> ZxResult { 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 { - 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) } diff --git a/zircon-syscall/src/pci.rs b/zircon-syscall/src/pci.rs index c11b00d4..3692faff 100644 --- a/zircon-syscall/src/pci.rs +++ b/zircon-syscall/src/pci.rs @@ -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);