MMIODescriptors are always physical

pull/110/head
Andre Richter 3 years ago
parent d09374710d
commit fa4a2de331
No known key found for this signature in database
GPG Key ID: 2116C1AB102F615E

@ -941,25 +941,22 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2/gi
diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs 15_virtual_mem_part2_mmio_remap/src/bsp/device_driver/arm/gicv2.rs diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs 15_virtual_mem_part2_mmio_remap/src/bsp/device_driver/arm/gicv2.rs
--- 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs --- 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs
+++ 15_virtual_mem_part2_mmio_remap/src/bsp/device_driver/arm/gicv2.rs +++ 15_virtual_mem_part2_mmio_remap/src/bsp/device_driver/arm/gicv2.rs
@@ -79,7 +79,11 @@ @@ -79,7 +79,8 @@
mod gicc; mod gicc;
mod gicd; mod gicd;
-use crate::{bsp, cpu, driver, exception, synchronization, synchronization::InitStateLock}; -use crate::{bsp, cpu, driver, exception, synchronization, synchronization::InitStateLock};
+use crate::{ +use crate::{bsp, cpu, driver, exception, memory, synchronization, synchronization::InitStateLock};
+ bsp, cpu, driver, exception, memory, memory::Physical, synchronization,
+ synchronization::InitStateLock,
+};
+use core::sync::atomic::{AtomicBool, Ordering}; +use core::sync::atomic::{AtomicBool, Ordering};
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Definitions // Private Definitions
@@ -96,12 +100,18 @@ @@ -96,12 +97,18 @@
/// Representation of the GIC. /// Representation of the GIC.
pub struct GICv2 { pub struct GICv2 {
+ gicd_phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, + gicd_mmio_descriptor: memory::mmu::MMIODescriptor,
+ gicc_phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, + gicc_mmio_descriptor: memory::mmu::MMIODescriptor,
+ +
/// The Distributor. /// The Distributor.
gicd: gicd::GICD, gicd: gicd::GICD,
@ -973,7 +970,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs
/// Stores registered IRQ handlers. Writable only during kernel init. RO afterwards. /// Stores registered IRQ handlers. Writable only during kernel init. RO afterwards.
handler_table: InitStateLock<HandlerTable>, handler_table: InitStateLock<HandlerTable>,
} }
@@ -118,11 +128,17 @@ @@ -118,11 +125,17 @@
/// ///
/// # Safety /// # Safety
/// ///
@ -981,21 +978,21 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs
- pub const unsafe fn new(gicd_mmio_start_addr: usize, gicc_mmio_start_addr: usize) -> Self { - pub const unsafe fn new(gicd_mmio_start_addr: usize, gicc_mmio_start_addr: usize) -> Self {
+ /// - The user must ensure to provide correct MMIO descriptors. + /// - The user must ensure to provide correct MMIO descriptors.
+ pub const unsafe fn new( + pub const unsafe fn new(
+ gicd_phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, + gicd_mmio_descriptor: memory::mmu::MMIODescriptor,
+ gicc_phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, + gicc_mmio_descriptor: memory::mmu::MMIODescriptor,
+ ) -> Self { + ) -> Self {
Self { Self {
- gicd: gicd::GICD::new(gicd_mmio_start_addr), - gicd: gicd::GICD::new(gicd_mmio_start_addr),
- gicc: gicc::GICC::new(gicc_mmio_start_addr), - gicc: gicc::GICC::new(gicc_mmio_start_addr),
+ gicd_phys_mmio_descriptor, + gicd_mmio_descriptor,
+ gicc_phys_mmio_descriptor, + gicc_mmio_descriptor,
+ gicd: gicd::GICD::new(gicd_phys_mmio_descriptor.start_addr().into_usize()), + gicd: gicd::GICD::new(gicd_mmio_descriptor.start_addr().into_usize()),
+ gicc: gicc::GICC::new(gicc_phys_mmio_descriptor.start_addr().into_usize()), + gicc: gicc::GICC::new(gicc_mmio_descriptor.start_addr().into_usize()),
+ is_mmio_remapped: AtomicBool::new(false), + is_mmio_remapped: AtomicBool::new(false),
handler_table: InitStateLock::new([None; Self::NUM_IRQS]), handler_table: InitStateLock::new([None; Self::NUM_IRQS]),
} }
} }
@@ -139,6 +155,22 @@ @@ -139,6 +152,22 @@
} }
unsafe fn init(&self) -> Result<(), &'static str> { unsafe fn init(&self) -> Result<(), &'static str> {
@ -1004,11 +1001,11 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs
+ let mut virt_addr; + let mut virt_addr;
+ +
+ // GICD + // GICD
+ virt_addr = memory::mmu::kernel_map_mmio("GICD", &self.gicd_phys_mmio_descriptor)?; + virt_addr = memory::mmu::kernel_map_mmio("GICD", &self.gicd_mmio_descriptor)?;
+ self.gicd.set_mmio(virt_addr.into_usize()); + self.gicd.set_mmio(virt_addr.into_usize());
+ +
+ // GICC + // GICC
+ virt_addr = memory::mmu::kernel_map_mmio("GICC", &self.gicc_phys_mmio_descriptor)?; + virt_addr = memory::mmu::kernel_map_mmio("GICC", &self.gicc_mmio_descriptor)?;
+ self.gicc.set_mmio(virt_addr.into_usize()); + self.gicc.set_mmio(virt_addr.into_usize());
+ +
+ // Conclude remapping. + // Conclude remapping.
@ -1027,9 +1024,8 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
use crate::{ use crate::{
- bsp::device_driver::common::MMIODerefWrapper, driver, synchronization, - bsp::device_driver::common::MMIODerefWrapper, driver, synchronization,
- synchronization::IRQSafeNullLock, + bsp::device_driver::common::MMIODerefWrapper, driver, memory, synchronization,
+ bsp::device_driver::common::MMIODerefWrapper, driver, memory, memory::Physical, synchronization::IRQSafeNullLock,
+ synchronization, synchronization::IRQSafeNullLock,
}; };
+use core::sync::atomic::{AtomicUsize, Ordering}; +use core::sync::atomic::{AtomicUsize, Ordering};
use register::{mmio::*, register_bitfields, register_structs}; use register::{mmio::*, register_bitfields, register_structs};
@ -1039,7 +1035,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
/// Representation of the GPIO HW. /// Representation of the GPIO HW.
pub struct GPIO { pub struct GPIO {
+ phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, + mmio_descriptor: memory::mmu::MMIODescriptor,
+ virt_mmio_start_addr: AtomicUsize, + virt_mmio_start_addr: AtomicUsize,
inner: IRQSafeNullLock<GPIOInner>, inner: IRQSafeNullLock<GPIOInner>,
} }
@ -1064,32 +1060,29 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
/// Disable pull-up/down on pins 14 and 15. /// Disable pull-up/down on pins 14 and 15.
#[cfg(feature = "bsp_rpi3")] #[cfg(feature = "bsp_rpi3")]
fn disable_pud_14_15_bcm2837(&mut self) { fn disable_pud_14_15_bcm2837(&mut self) {
@@ -190,10 +206,14 @@ @@ -190,10 +206,12 @@
/// ///
/// # Safety /// # Safety
/// ///
- /// - The user must ensure to provide a correct MMIO start address. - /// - The user must ensure to provide a correct MMIO start address.
- pub const unsafe fn new(mmio_start_addr: usize) -> Self { - pub const unsafe fn new(mmio_start_addr: usize) -> Self {
+ /// - The user must ensure to provide correct MMIO descriptors. + /// - The user must ensure to provide correct MMIO descriptors.
+ pub const unsafe fn new(phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>) -> Self { + pub const unsafe fn new(mmio_descriptor: memory::mmu::MMIODescriptor) -> Self {
Self { Self {
- inner: IRQSafeNullLock::new(GPIOInner::new(mmio_start_addr)), - inner: IRQSafeNullLock::new(GPIOInner::new(mmio_start_addr)),
+ phys_mmio_descriptor, + mmio_descriptor,
+ virt_mmio_start_addr: AtomicUsize::new(0), + virt_mmio_start_addr: AtomicUsize::new(0),
+ inner: IRQSafeNullLock::new(GPIOInner::new( + inner: IRQSafeNullLock::new(GPIOInner::new(mmio_descriptor.start_addr().into_usize())),
+ phys_mmio_descriptor.start_addr().into_usize(),
+ )),
} }
} }
@@ -212,4 +232,27 @@ @@ -212,4 +230,26 @@
fn compatible(&self) -> &'static str { fn compatible(&self) -> &'static str {
"BCM GPIO" "BCM GPIO"
} }
+ +
+ unsafe fn init(&self) -> Result<(), &'static str> { + unsafe fn init(&self) -> Result<(), &'static str> {
+ let virt_addr = + let virt_addr = memory::mmu::kernel_map_mmio(self.compatible(), &self.mmio_descriptor)?;
+ memory::mmu::kernel_map_mmio(self.compatible(), &self.phys_mmio_descriptor)?;
+ +
+ self.inner + self.inner
+ .lock(|inner| inner.init(Some(virt_addr.into_usize())))?; + .lock(|inner| inner.init(Some(virt_addr.into_usize())))?;
@ -1114,7 +1107,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs 15_virtual_mem_part2_mmio_remap/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs 15_virtual_mem_part2_mmio_remap/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs
--- 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs --- 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs
+++ 15_virtual_mem_part2_mmio_remap/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs +++ 15_virtual_mem_part2_mmio_remap/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs
@@ -2,12 +2,14 @@ @@ -2,12 +2,12 @@
// //
// Copyright (c) 2020-2021 Andre Richter <andre.o.richter@gmail.com> // Copyright (c) 2020-2021 Andre Richter <andre.o.richter@gmail.com>
@ -1125,17 +1118,15 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
use crate::{ use crate::{
bsp::device_driver::common::MMIODerefWrapper, bsp::device_driver::common::MMIODerefWrapper,
- exception, synchronization, - exception, synchronization,
+ driver, exception, memory, + driver, exception, memory, synchronization,
+ memory::Physical,
+ synchronization,
synchronization::{IRQSafeNullLock, InitStateLock}, synchronization::{IRQSafeNullLock, InitStateLock},
}; };
use register::{mmio::*, register_structs}; use register::{mmio::*, register_structs};
@@ -51,11 +53,13 @@ @@ -51,11 +51,13 @@
/// Representation of the peripheral interrupt controller. /// Representation of the peripheral interrupt controller.
pub struct PeripheralIC { pub struct PeripheralIC {
+ phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, + mmio_descriptor: memory::mmu::MMIODescriptor,
+ +
/// Access to write registers is guarded with a lock. /// Access to write registers is guarded with a lock.
wo_registers: IRQSafeNullLock<WriteOnlyRegisters>, wo_registers: IRQSafeNullLock<WriteOnlyRegisters>,
@ -1146,20 +1137,20 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
/// Stores registered IRQ handlers. Writable only during kernel init. RO afterwards. /// Stores registered IRQ handlers. Writable only during kernel init. RO afterwards.
handler_table: InitStateLock<HandlerTable>, handler_table: InitStateLock<HandlerTable>,
@@ -70,21 +74,26 @@ @@ -70,21 +72,26 @@
/// ///
/// # Safety /// # Safety
/// ///
- /// - The user must ensure to provide a correct MMIO start address. - /// - The user must ensure to provide a correct MMIO start address.
- pub const unsafe fn new(mmio_start_addr: usize) -> Self { - pub const unsafe fn new(mmio_start_addr: usize) -> Self {
+ /// - The user must ensure to provide correct MMIO descriptors. + /// - The user must ensure to provide correct MMIO descriptors.
+ pub const unsafe fn new(phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>) -> Self { + pub const unsafe fn new(mmio_descriptor: memory::mmu::MMIODescriptor) -> Self {
+ let addr = phys_mmio_descriptor.start_addr().into_usize(); + let addr = mmio_descriptor.start_addr().into_usize();
+ +
Self { Self {
- wo_registers: IRQSafeNullLock::new(WriteOnlyRegisters::new(mmio_start_addr)), - wo_registers: IRQSafeNullLock::new(WriteOnlyRegisters::new(mmio_start_addr)),
- ro_registers: ReadOnlyRegisters::new(mmio_start_addr), - ro_registers: ReadOnlyRegisters::new(mmio_start_addr),
+ phys_mmio_descriptor, + mmio_descriptor,
+ wo_registers: IRQSafeNullLock::new(WriteOnlyRegisters::new(addr)), + wo_registers: IRQSafeNullLock::new(WriteOnlyRegisters::new(addr)),
+ ro_registers: InitStateLock::new(ReadOnlyRegisters::new(addr)), + ro_registers: InitStateLock::new(ReadOnlyRegisters::new(addr)),
handler_table: InitStateLock::new([None; InterruptController::NUM_PERIPHERAL_IRQS]), handler_table: InitStateLock::new([None; InterruptController::NUM_PERIPHERAL_IRQS]),
@ -1180,7 +1171,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
} }
} }
@@ -93,6 +102,25 @@ @@ -93,6 +100,24 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
use synchronization::interface::{Mutex, ReadWriteEx}; use synchronization::interface::{Mutex, ReadWriteEx};
@ -1191,8 +1182,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
+ +
+ unsafe fn init(&self) -> Result<(), &'static str> { + unsafe fn init(&self) -> Result<(), &'static str> {
+ let virt_addr = + let virt_addr =
+ memory::mmu::kernel_map_mmio(self.compatible(), &self.phys_mmio_descriptor)? + memory::mmu::kernel_map_mmio(self.compatible(), &self.mmio_descriptor)?.into_usize();
+ .into_usize();
+ +
+ self.wo_registers + self.wo_registers
+ .lock(|regs| *regs = WriteOnlyRegisters::new(virt_addr)); + .lock(|regs| *regs = WriteOnlyRegisters::new(virt_addr));
@ -1215,7 +1205,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
mod peripheral_ic; mod peripheral_ic;
-use crate::{driver, exception}; -use crate::{driver, exception};
+use crate::{driver, exception, memory, memory::Physical}; +use crate::{driver, exception, memory};
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Definitions // Private Definitions
@ -1227,12 +1217,12 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
- pub const unsafe fn new(_local_mmio_start_addr: usize, periph_mmio_start_addr: usize) -> Self { - pub const unsafe fn new(_local_mmio_start_addr: usize, periph_mmio_start_addr: usize) -> Self {
+ /// - The user must ensure to provide correct MMIO descriptors. + /// - The user must ensure to provide correct MMIO descriptors.
+ pub const unsafe fn new( + pub const unsafe fn new(
+ _phys_local_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, + _local_mmio_descriptor: memory::mmu::MMIODescriptor,
+ phys_periph_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, + periph_mmio_descriptor: memory::mmu::MMIODescriptor,
+ ) -> Self { + ) -> Self {
Self { Self {
- periph: peripheral_ic::PeripheralIC::new(periph_mmio_start_addr), - periph: peripheral_ic::PeripheralIC::new(periph_mmio_start_addr),
+ periph: peripheral_ic::PeripheralIC::new(phys_periph_mmio_descriptor), + periph: peripheral_ic::PeripheralIC::new(periph_mmio_descriptor),
} }
} }
} }
@ -1256,15 +1246,14 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
use crate::{ use crate::{
- bsp, bsp::device_driver::common::MMIODerefWrapper, console, cpu, driver, exception, - bsp, bsp::device_driver::common::MMIODerefWrapper, console, cpu, driver, exception,
- synchronization, synchronization::IRQSafeNullLock,
+ bsp, bsp::device_driver::common::MMIODerefWrapper, console, cpu, driver, exception, memory, + bsp, bsp::device_driver::common::MMIODerefWrapper, console, cpu, driver, exception, memory,
+ memory::Physical, synchronization, synchronization::IRQSafeNullLock, synchronization, synchronization::IRQSafeNullLock,
+}; };
-use core::fmt;
+use core::{ +use core::{
+ fmt, + fmt,
+ sync::atomic::{AtomicUsize, Ordering}, + sync::atomic::{AtomicUsize, Ordering},
}; +};
-use core::fmt;
use register::{mmio::*, register_bitfields, register_structs}; use register::{mmio::*, register_bitfields, register_structs};
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -1272,7 +1261,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
/// Representation of the UART. /// Representation of the UART.
pub struct PL011Uart { pub struct PL011Uart {
+ phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, + mmio_descriptor: memory::mmu::MMIODescriptor,
+ virt_mmio_start_addr: AtomicUsize, + virt_mmio_start_addr: AtomicUsize,
inner: IRQSafeNullLock<PL011UartInner>, inner: IRQSafeNullLock<PL011UartInner>,
irq_number: bsp::device_driver::IRQNumber, irq_number: bsp::device_driver::IRQNumber,
@ -1312,26 +1301,25 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
+ /// - The user must ensure to provide correct IRQ numbers. + /// - The user must ensure to provide correct IRQ numbers.
pub const unsafe fn new( pub const unsafe fn new(
- mmio_start_addr: usize, - mmio_start_addr: usize,
+ phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, + mmio_descriptor: memory::mmu::MMIODescriptor,
irq_number: bsp::device_driver::IRQNumber, irq_number: bsp::device_driver::IRQNumber,
) -> Self { ) -> Self {
Self { Self {
- inner: IRQSafeNullLock::new(PL011UartInner::new(mmio_start_addr)), - inner: IRQSafeNullLock::new(PL011UartInner::new(mmio_start_addr)),
+ phys_mmio_descriptor, + mmio_descriptor,
+ virt_mmio_start_addr: AtomicUsize::new(0), + virt_mmio_start_addr: AtomicUsize::new(0),
+ inner: IRQSafeNullLock::new(PL011UartInner::new( + inner: IRQSafeNullLock::new(PL011UartInner::new(
+ phys_mmio_descriptor.start_addr().into_usize(), + mmio_descriptor.start_addr().into_usize(),
+ )), + )),
irq_number, irq_number,
} }
} }
@@ -413,7 +433,14 @@ @@ -413,7 +433,13 @@
} }
unsafe fn init(&self) -> Result<(), &'static str> { unsafe fn init(&self) -> Result<(), &'static str> {
- self.inner.lock(|inner| inner.init()); - self.inner.lock(|inner| inner.init());
+ let virt_addr = + let virt_addr = memory::mmu::kernel_map_mmio(self.compatible(), &self.mmio_descriptor)?;
+ memory::mmu::kernel_map_mmio(self.compatible(), &self.phys_mmio_descriptor)?;
+ +
+ self.inner + self.inner
+ .lock(|inner| inner.init(Some(virt_addr.into_usize())))?; + .lock(|inner| inner.init(Some(virt_addr.into_usize())))?;
@ -1341,7 +1329,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_
Ok(()) Ok(())
} }
@@ -432,6 +459,16 @@ @@ -432,6 +458,16 @@
Ok(()) Ok(())
} }
@ -2319,10 +2307,10 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/memory/mmu/mapping_record.rs 1
+} +}
+ +
+pub fn kernel_find_and_insert_mmio_duplicate( +pub fn kernel_find_and_insert_mmio_duplicate(
+ phys_mmio_descriptor: &MMIODescriptor<Physical>, + mmio_descriptor: &MMIODescriptor,
+ new_user: &'static str, + new_user: &'static str,
+) -> Option<Address<Virtual>> { +) -> Option<Address<Virtual>> {
+ let phys_pages: PageSliceDescriptor<Physical> = phys_mmio_descriptor.clone().into(); + let phys_pages: PageSliceDescriptor<Physical> = mmio_descriptor.clone().into();
+ +
+ KERNEL_MAPPING_RECORD.write(|mr| { + KERNEL_MAPPING_RECORD.write(|mr| {
+ let dup = mr.find_duplicate(&phys_pages)?; + let dup = mr.find_duplicate(&phys_pages)?;
@ -2512,8 +2500,8 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/memory/mmu/types.rs 15_virtual
+ +
+/// An MMIO descriptor for use in device drivers. +/// An MMIO descriptor for use in device drivers.
+#[derive(Copy, Clone)] +#[derive(Copy, Clone)]
+pub struct MMIODescriptor<ATYPE: AddressType> { +pub struct MMIODescriptor {
+ start_addr: Address<ATYPE>, + start_addr: Address<Physical>,
+ size: usize, + size: usize,
+} +}
+ +
@ -2602,8 +2590,8 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/memory/mmu/types.rs 15_virtual
+ } + }
+} +}
+ +
+impl<ATYPE: AddressType> From<MMIODescriptor<ATYPE>> for PageSliceDescriptor<ATYPE> { +impl From<MMIODescriptor> for PageSliceDescriptor<Physical> {
+ fn from(desc: MMIODescriptor<ATYPE>) -> Self { + fn from(desc: MMIODescriptor) -> Self {
+ let start_page_addr = desc + let start_page_addr = desc
+ .start_addr + .start_addr
+ .align_down(bsp::memory::mmu::KernelGranule::SIZE); + .align_down(bsp::memory::mmu::KernelGranule::SIZE);
@ -2623,21 +2611,21 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/memory/mmu/types.rs 15_virtual
+// MMIODescriptor +// MMIODescriptor
+//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------
+ +
+impl<ATYPE: AddressType> MMIODescriptor<ATYPE> { +impl MMIODescriptor {
+ /// Create an instance. + /// Create an instance.
+ pub const fn new(start_addr: Address<ATYPE>, size: usize) -> Self { + pub const fn new(start_addr: Address<Physical>, size: usize) -> Self {
+ assert!(size > 0); + assert!(size > 0);
+ +
+ Self { start_addr, size } + Self { start_addr, size }
+ } + }
+ +
+ /// Return the start address. + /// Return the start address.
+ pub const fn start_addr(&self) -> Address<ATYPE> { + pub const fn start_addr(&self) -> Address<Physical> {
+ self.start_addr + self.start_addr
+ } + }
+ +
+ /// Return the inclusive end address. + /// Return the inclusive end address.
+ pub fn end_addr_inclusive(&self) -> Address<ATYPE> { + pub fn end_addr_inclusive(&self) -> Address<Physical> {
+ self.start_addr + (self.size - 1) + self.start_addr + (self.size - 1)
+ } + }
+ +
@ -2970,15 +2958,15 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/memory/mmu.rs 15_virtual_mem_p
+/// - Same as `kernel_map_pages_at_unchecked()`, minus the aliasing part. +/// - Same as `kernel_map_pages_at_unchecked()`, minus the aliasing part.
+pub unsafe fn kernel_map_mmio( +pub unsafe fn kernel_map_mmio(
+ name: &'static str, + name: &'static str,
+ phys_mmio_descriptor: &MMIODescriptor<Physical>, + mmio_descriptor: &MMIODescriptor,
+) -> Result<Address<Virtual>, &'static str> { +) -> Result<Address<Virtual>, &'static str> {
+ let phys_pages: PageSliceDescriptor<Physical> = phys_mmio_descriptor.clone().into(); + let phys_pages: PageSliceDescriptor<Physical> = mmio_descriptor.clone().into();
+ let offset_into_start_page = + let offset_into_start_page =
+ phys_mmio_descriptor.start_addr().into_usize() & bsp::memory::mmu::KernelGranule::MASK; + mmio_descriptor.start_addr().into_usize() & bsp::memory::mmu::KernelGranule::MASK;
+ +
+ // Check if an identical page slice has been mapped for another driver. If so, reuse it. + // Check if an identical page slice has been mapped for another driver. If so, reuse it.
+ let virt_addr = if let Some(addr) = + let virt_addr = if let Some(addr) =
+ mapping_record::kernel_find_and_insert_mmio_duplicate(phys_mmio_descriptor, name) + mapping_record::kernel_find_and_insert_mmio_duplicate(mmio_descriptor, name)
+ { + {
+ addr + addr
+ // Otherwise, allocate a new virtual page slice and map it. + // Otherwise, allocate a new virtual page slice and map it.

@ -79,10 +79,7 @@
mod gicc; mod gicc;
mod gicd; mod gicd;
use crate::{ use crate::{bsp, cpu, driver, exception, memory, synchronization, synchronization::InitStateLock};
bsp, cpu, driver, exception, memory, memory::Physical, synchronization,
synchronization::InitStateLock,
};
use core::sync::atomic::{AtomicBool, Ordering}; use core::sync::atomic::{AtomicBool, Ordering};
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -100,8 +97,8 @@ pub type IRQNumber = exception::asynchronous::IRQNumber<{ GICv2::MAX_IRQ_NUMBER
/// Representation of the GIC. /// Representation of the GIC.
pub struct GICv2 { pub struct GICv2 {
gicd_phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, gicd_mmio_descriptor: memory::mmu::MMIODescriptor,
gicc_phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, gicc_mmio_descriptor: memory::mmu::MMIODescriptor,
/// The Distributor. /// The Distributor.
gicd: gicd::GICD, gicd: gicd::GICD,
@ -130,14 +127,14 @@ impl GICv2 {
/// ///
/// - The user must ensure to provide correct MMIO descriptors. /// - The user must ensure to provide correct MMIO descriptors.
pub const unsafe fn new( pub const unsafe fn new(
gicd_phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, gicd_mmio_descriptor: memory::mmu::MMIODescriptor,
gicc_phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, gicc_mmio_descriptor: memory::mmu::MMIODescriptor,
) -> Self { ) -> Self {
Self { Self {
gicd_phys_mmio_descriptor, gicd_mmio_descriptor,
gicc_phys_mmio_descriptor, gicc_mmio_descriptor,
gicd: gicd::GICD::new(gicd_phys_mmio_descriptor.start_addr().into_usize()), gicd: gicd::GICD::new(gicd_mmio_descriptor.start_addr().into_usize()),
gicc: gicc::GICC::new(gicc_phys_mmio_descriptor.start_addr().into_usize()), gicc: gicc::GICC::new(gicc_mmio_descriptor.start_addr().into_usize()),
is_mmio_remapped: AtomicBool::new(false), is_mmio_remapped: AtomicBool::new(false),
handler_table: InitStateLock::new([None; Self::NUM_IRQS]), handler_table: InitStateLock::new([None; Self::NUM_IRQS]),
} }
@ -160,11 +157,11 @@ impl driver::interface::DeviceDriver for GICv2 {
let mut virt_addr; let mut virt_addr;
// GICD // GICD
virt_addr = memory::mmu::kernel_map_mmio("GICD", &self.gicd_phys_mmio_descriptor)?; virt_addr = memory::mmu::kernel_map_mmio("GICD", &self.gicd_mmio_descriptor)?;
self.gicd.set_mmio(virt_addr.into_usize()); self.gicd.set_mmio(virt_addr.into_usize());
// GICC // GICC
virt_addr = memory::mmu::kernel_map_mmio("GICC", &self.gicc_phys_mmio_descriptor)?; virt_addr = memory::mmu::kernel_map_mmio("GICC", &self.gicc_mmio_descriptor)?;
self.gicc.set_mmio(virt_addr.into_usize()); self.gicc.set_mmio(virt_addr.into_usize());
// Conclude remapping. // Conclude remapping.

@ -5,8 +5,8 @@
//! GPIO Driver. //! GPIO Driver.
use crate::{ use crate::{
bsp::device_driver::common::MMIODerefWrapper, driver, memory, memory::Physical, bsp::device_driver::common::MMIODerefWrapper, driver, memory, synchronization,
synchronization, synchronization::IRQSafeNullLock, synchronization::IRQSafeNullLock,
}; };
use core::sync::atomic::{AtomicUsize, Ordering}; use core::sync::atomic::{AtomicUsize, Ordering};
use register::{mmio::*, register_bitfields, register_structs}; use register::{mmio::*, register_bitfields, register_structs};
@ -118,7 +118,7 @@ pub use GPIOInner as PanicGPIO;
/// Representation of the GPIO HW. /// Representation of the GPIO HW.
pub struct GPIO { pub struct GPIO {
phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, mmio_descriptor: memory::mmu::MMIODescriptor,
virt_mmio_start_addr: AtomicUsize, virt_mmio_start_addr: AtomicUsize,
inner: IRQSafeNullLock<GPIOInner>, inner: IRQSafeNullLock<GPIOInner>,
} }
@ -207,13 +207,11 @@ impl GPIO {
/// # Safety /// # Safety
/// ///
/// - The user must ensure to provide correct MMIO descriptors. /// - The user must ensure to provide correct MMIO descriptors.
pub const unsafe fn new(phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>) -> Self { pub const unsafe fn new(mmio_descriptor: memory::mmu::MMIODescriptor) -> Self {
Self { Self {
phys_mmio_descriptor, mmio_descriptor,
virt_mmio_start_addr: AtomicUsize::new(0), virt_mmio_start_addr: AtomicUsize::new(0),
inner: IRQSafeNullLock::new(GPIOInner::new( inner: IRQSafeNullLock::new(GPIOInner::new(mmio_descriptor.start_addr().into_usize())),
phys_mmio_descriptor.start_addr().into_usize(),
)),
} }
} }
@ -234,8 +232,7 @@ impl driver::interface::DeviceDriver for GPIO {
} }
unsafe fn init(&self) -> Result<(), &'static str> { unsafe fn init(&self) -> Result<(), &'static str> {
let virt_addr = let virt_addr = memory::mmu::kernel_map_mmio(self.compatible(), &self.mmio_descriptor)?;
memory::mmu::kernel_map_mmio(self.compatible(), &self.phys_mmio_descriptor)?;
self.inner self.inner
.lock(|inner| inner.init(Some(virt_addr.into_usize())))?; .lock(|inner| inner.init(Some(virt_addr.into_usize())))?;

@ -6,7 +6,7 @@
mod peripheral_ic; mod peripheral_ic;
use crate::{driver, exception, memory, memory::Physical}; use crate::{driver, exception, memory};
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Definitions // Private Definitions
@ -80,11 +80,11 @@ impl InterruptController {
/// ///
/// - The user must ensure to provide correct MMIO descriptors. /// - The user must ensure to provide correct MMIO descriptors.
pub const unsafe fn new( pub const unsafe fn new(
_phys_local_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, _local_mmio_descriptor: memory::mmu::MMIODescriptor,
phys_periph_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, periph_mmio_descriptor: memory::mmu::MMIODescriptor,
) -> Self { ) -> Self {
Self { Self {
periph: peripheral_ic::PeripheralIC::new(phys_periph_mmio_descriptor), periph: peripheral_ic::PeripheralIC::new(periph_mmio_descriptor),
} }
} }
} }

@ -7,9 +7,7 @@
use super::{InterruptController, PendingIRQs, PeripheralIRQ}; use super::{InterruptController, PendingIRQs, PeripheralIRQ};
use crate::{ use crate::{
bsp::device_driver::common::MMIODerefWrapper, bsp::device_driver::common::MMIODerefWrapper,
driver, exception, memory, driver, exception, memory, synchronization,
memory::Physical,
synchronization,
synchronization::{IRQSafeNullLock, InitStateLock}, synchronization::{IRQSafeNullLock, InitStateLock},
}; };
use register::{mmio::*, register_structs}; use register::{mmio::*, register_structs};
@ -53,7 +51,7 @@ type HandlerTable =
/// Representation of the peripheral interrupt controller. /// Representation of the peripheral interrupt controller.
pub struct PeripheralIC { pub struct PeripheralIC {
phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, mmio_descriptor: memory::mmu::MMIODescriptor,
/// Access to write registers is guarded with a lock. /// Access to write registers is guarded with a lock.
wo_registers: IRQSafeNullLock<WriteOnlyRegisters>, wo_registers: IRQSafeNullLock<WriteOnlyRegisters>,
@ -75,11 +73,11 @@ impl PeripheralIC {
/// # Safety /// # Safety
/// ///
/// - The user must ensure to provide correct MMIO descriptors. /// - The user must ensure to provide correct MMIO descriptors.
pub const unsafe fn new(phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>) -> Self { pub const unsafe fn new(mmio_descriptor: memory::mmu::MMIODescriptor) -> Self {
let addr = phys_mmio_descriptor.start_addr().into_usize(); let addr = mmio_descriptor.start_addr().into_usize();
Self { Self {
phys_mmio_descriptor, mmio_descriptor,
wo_registers: IRQSafeNullLock::new(WriteOnlyRegisters::new(addr)), wo_registers: IRQSafeNullLock::new(WriteOnlyRegisters::new(addr)),
ro_registers: InitStateLock::new(ReadOnlyRegisters::new(addr)), ro_registers: InitStateLock::new(ReadOnlyRegisters::new(addr)),
handler_table: InitStateLock::new([None; InterruptController::NUM_PERIPHERAL_IRQS]), handler_table: InitStateLock::new([None; InterruptController::NUM_PERIPHERAL_IRQS]),
@ -109,8 +107,7 @@ impl driver::interface::DeviceDriver for PeripheralIC {
unsafe fn init(&self) -> Result<(), &'static str> { unsafe fn init(&self) -> Result<(), &'static str> {
let virt_addr = let virt_addr =
memory::mmu::kernel_map_mmio(self.compatible(), &self.phys_mmio_descriptor)? memory::mmu::kernel_map_mmio(self.compatible(), &self.mmio_descriptor)?.into_usize();
.into_usize();
self.wo_registers self.wo_registers
.lock(|regs| *regs = WriteOnlyRegisters::new(virt_addr)); .lock(|regs| *regs = WriteOnlyRegisters::new(virt_addr));

@ -11,7 +11,7 @@
use crate::{ use crate::{
bsp, bsp::device_driver::common::MMIODerefWrapper, console, cpu, driver, exception, memory, bsp, bsp::device_driver::common::MMIODerefWrapper, console, cpu, driver, exception, memory,
memory::Physical, synchronization, synchronization::IRQSafeNullLock, synchronization, synchronization::IRQSafeNullLock,
}; };
use core::{ use core::{
fmt, fmt,
@ -235,7 +235,7 @@ pub use PL011UartInner as PanicUart;
/// Representation of the UART. /// Representation of the UART.
pub struct PL011Uart { pub struct PL011Uart {
phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, mmio_descriptor: memory::mmu::MMIODescriptor,
virt_mmio_start_addr: AtomicUsize, virt_mmio_start_addr: AtomicUsize,
inner: IRQSafeNullLock<PL011UartInner>, inner: IRQSafeNullLock<PL011UartInner>,
irq_number: bsp::device_driver::IRQNumber, irq_number: bsp::device_driver::IRQNumber,
@ -408,14 +408,14 @@ impl PL011Uart {
/// - The user must ensure to provide correct MMIO descriptors. /// - The user must ensure to provide correct MMIO descriptors.
/// - The user must ensure to provide correct IRQ numbers. /// - The user must ensure to provide correct IRQ numbers.
pub const unsafe fn new( pub const unsafe fn new(
phys_mmio_descriptor: memory::mmu::MMIODescriptor<Physical>, mmio_descriptor: memory::mmu::MMIODescriptor,
irq_number: bsp::device_driver::IRQNumber, irq_number: bsp::device_driver::IRQNumber,
) -> Self { ) -> Self {
Self { Self {
phys_mmio_descriptor, mmio_descriptor,
virt_mmio_start_addr: AtomicUsize::new(0), virt_mmio_start_addr: AtomicUsize::new(0),
inner: IRQSafeNullLock::new(PL011UartInner::new( inner: IRQSafeNullLock::new(PL011UartInner::new(
phys_mmio_descriptor.start_addr().into_usize(), mmio_descriptor.start_addr().into_usize(),
)), )),
irq_number, irq_number,
} }
@ -433,8 +433,7 @@ impl driver::interface::DeviceDriver for PL011Uart {
} }
unsafe fn init(&self) -> Result<(), &'static str> { unsafe fn init(&self) -> Result<(), &'static str> {
let virt_addr = let virt_addr = memory::mmu::kernel_map_mmio(self.compatible(), &self.mmio_descriptor)?;
memory::mmu::kernel_map_mmio(self.compatible(), &self.phys_mmio_descriptor)?;
self.inner self.inner
.lock(|inner| inner.init(Some(virt_addr.into_usize())))?; .lock(|inner| inner.init(Some(virt_addr.into_usize())))?;

@ -180,15 +180,15 @@ pub unsafe fn kernel_map_pages_at(
/// - Same as `kernel_map_pages_at_unchecked()`, minus the aliasing part. /// - Same as `kernel_map_pages_at_unchecked()`, minus the aliasing part.
pub unsafe fn kernel_map_mmio( pub unsafe fn kernel_map_mmio(
name: &'static str, name: &'static str,
phys_mmio_descriptor: &MMIODescriptor<Physical>, mmio_descriptor: &MMIODescriptor,
) -> Result<Address<Virtual>, &'static str> { ) -> Result<Address<Virtual>, &'static str> {
let phys_pages: PageSliceDescriptor<Physical> = phys_mmio_descriptor.clone().into(); let phys_pages: PageSliceDescriptor<Physical> = mmio_descriptor.clone().into();
let offset_into_start_page = let offset_into_start_page =
phys_mmio_descriptor.start_addr().into_usize() & bsp::memory::mmu::KernelGranule::MASK; mmio_descriptor.start_addr().into_usize() & bsp::memory::mmu::KernelGranule::MASK;
// Check if an identical page slice has been mapped for another driver. If so, reuse it. // Check if an identical page slice has been mapped for another driver. If so, reuse it.
let virt_addr = if let Some(addr) = let virt_addr = if let Some(addr) =
mapping_record::kernel_find_and_insert_mmio_duplicate(phys_mmio_descriptor, name) mapping_record::kernel_find_and_insert_mmio_duplicate(mmio_descriptor, name)
{ {
addr addr
// Otherwise, allocate a new virtual page slice and map it. // Otherwise, allocate a new virtual page slice and map it.

@ -199,10 +199,10 @@ pub fn kernel_add(
} }
pub fn kernel_find_and_insert_mmio_duplicate( pub fn kernel_find_and_insert_mmio_duplicate(
phys_mmio_descriptor: &MMIODescriptor<Physical>, mmio_descriptor: &MMIODescriptor,
new_user: &'static str, new_user: &'static str,
) -> Option<Address<Virtual>> { ) -> Option<Address<Virtual>> {
let phys_pages: PageSliceDescriptor<Physical> = phys_mmio_descriptor.clone().into(); let phys_pages: PageSliceDescriptor<Physical> = mmio_descriptor.clone().into();
KERNEL_MAPPING_RECORD.write(|mr| { KERNEL_MAPPING_RECORD.write(|mr| {
let dup = mr.find_duplicate(&phys_pages)?; let dup = mr.find_duplicate(&phys_pages)?;

@ -55,8 +55,8 @@ pub struct AttributeFields {
/// An MMIO descriptor for use in device drivers. /// An MMIO descriptor for use in device drivers.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct MMIODescriptor<ATYPE: AddressType> { pub struct MMIODescriptor {
start_addr: Address<ATYPE>, start_addr: Address<Physical>,
size: usize, size: usize,
} }
@ -145,8 +145,8 @@ impl From<PageSliceDescriptor<Virtual>> for PageSliceDescriptor<Physical> {
} }
} }
impl<ATYPE: AddressType> From<MMIODescriptor<ATYPE>> for PageSliceDescriptor<ATYPE> { impl From<MMIODescriptor> for PageSliceDescriptor<Physical> {
fn from(desc: MMIODescriptor<ATYPE>) -> Self { fn from(desc: MMIODescriptor) -> Self {
let start_page_addr = desc let start_page_addr = desc
.start_addr .start_addr
.align_down(bsp::memory::mmu::KernelGranule::SIZE); .align_down(bsp::memory::mmu::KernelGranule::SIZE);
@ -166,21 +166,21 @@ impl<ATYPE: AddressType> From<MMIODescriptor<ATYPE>> for PageSliceDescriptor<ATY
// MMIODescriptor // MMIODescriptor
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
impl<ATYPE: AddressType> MMIODescriptor<ATYPE> { impl MMIODescriptor {
/// Create an instance. /// Create an instance.
pub const fn new(start_addr: Address<ATYPE>, size: usize) -> Self { pub const fn new(start_addr: Address<Physical>, size: usize) -> Self {
assert!(size > 0); assert!(size > 0);
Self { start_addr, size } Self { start_addr, size }
} }
/// Return the start address. /// Return the start address.
pub const fn start_addr(&self) -> Address<ATYPE> { pub const fn start_addr(&self) -> Address<Physical> {
self.start_addr self.start_addr
} }
/// Return the inclusive end address. /// Return the inclusive end address.
pub fn end_addr_inclusive(&self) -> Address<ATYPE> { pub fn end_addr_inclusive(&self) -> Address<Physical> {
self.start_addr + (self.size - 1) self.start_addr + (self.size - 1)
} }

Loading…
Cancel
Save