@@ -5,8 +5,11 @@ use core::{
55 array,
66 convert:: TryFrom ,
77 fmt:: { self , Display , Formatter } ,
8+ ops:: Deref ,
9+ ptr:: NonNull ,
810} ;
911use log:: warn;
12+ use safe_mmio:: { fields:: ReadPureWrite , UniqueMmioPointer } ;
1013use thiserror:: Error ;
1114
1215const INVALID_READ : u32 = 0xffffffff ;
@@ -349,12 +352,12 @@ pub trait ConfigurationAccess {
349352/// `ConfigurationAccess` implementation for memory-mapped access to a PCI root complex, via either
350353/// a 16 MiB region for the PCI Configuration Access Mechanism or a 256 MiB region for the PCIe
351354/// Enhanced Configuration Access Mechanism.
352- pub struct MmioCam {
353- mmio_base : * mut u32 ,
355+ pub struct MmioCam < ' a > {
356+ mmio : UniqueMmioPointer < ' a , [ ReadPureWrite < u32 > ] > ,
354357 cam : Cam ,
355358}
356359
357- impl MmioCam {
360+ impl MmioCam < ' _ > {
358361 /// Wraps the PCI root complex with the given MMIO base address.
359362 ///
360363 /// Panics if the base address is not aligned to a 4-byte boundary.
@@ -363,52 +366,47 @@ impl MmioCam {
363366 ///
364367 /// `mmio_base` must be a valid pointer to an appropriately-mapped MMIO region of at least
365368 /// 16 MiB (if `cam == Cam::MmioCam`) or 256 MiB (if `cam == Cam::Ecam`). The pointer must be
366- /// valid for the entire lifetime of the program (i.e. `'static`) , which implies that no Rust
367- /// references may be used to access any of the memory region at any point .
369+ /// valid for the lifetime `'a` , which implies that no Rust references may be used to access any
370+ /// of the memory region at least during that lifetime .
368371 pub unsafe fn new ( mmio_base : * mut u8 , cam : Cam ) -> Self {
369372 assert ! ( mmio_base as usize & 0x3 == 0 ) ;
370373 Self {
371- mmio_base : mmio_base as * mut u32 ,
374+ mmio : UniqueMmioPointer :: new ( NonNull :: slice_from_raw_parts (
375+ NonNull :: new ( mmio_base as * mut ReadPureWrite < u32 > ) . unwrap ( ) ,
376+ cam. size ( ) as usize / size_of :: < u32 > ( ) ,
377+ ) ) ,
372378 cam,
373379 }
374380 }
375381}
376382
377- impl ConfigurationAccess for MmioCam {
383+ impl ConfigurationAccess for MmioCam < ' _ > {
378384 fn read_word ( & self , device_function : DeviceFunction , register_offset : u8 ) -> u32 {
379385 let address = self . cam . cam_offset ( device_function, register_offset) ;
380- // SAFETY: Both the `mmio_base` and the address offset are properly aligned,
381- // and the resulting pointer is within the MMIO range of the CAM.
382- unsafe {
383- // Right shift to convert from byte offset to word offset.
384- ( self . mmio_base . add ( ( address >> 2 ) as usize ) ) . read_volatile ( )
385- }
386+ // Right shift to convert from byte offset to word offset.
387+ self . mmio
388+ . deref ( )
389+ . get ( ( address >> 2 ) as usize )
390+ . unwrap ( )
391+ . read ( )
386392 }
387393
388394 fn write_word ( & mut self , device_function : DeviceFunction , register_offset : u8 , data : u32 ) {
389395 let address = self . cam . cam_offset ( device_function, register_offset) ;
390- // SAFETY: Both the `mmio_base` and the address offset are properly aligned,
391- // and the resulting pointer is within the MMIO range of the CAM.
392- unsafe {
393- // Right shift to convert from byte offset to word offset.
394- ( self . mmio_base . add ( ( address >> 2 ) as usize ) ) . write_volatile ( data)
395- }
396+ self . mmio . get ( ( address >> 2 ) as usize ) . unwrap ( ) . write ( data) ;
396397 }
397398
398399 unsafe fn unsafe_clone ( & self ) -> Self {
399400 Self {
400- mmio_base : self . mmio_base ,
401+ mmio : UniqueMmioPointer :: new ( NonNull :: new ( self . mmio . ptr ( ) . cast_mut ( ) ) . unwrap ( ) ) ,
401402 cam : self . cam ,
402403 }
403404 }
404405}
405406
406- // SAFETY: `mmio_base` is only used for MMIO, which can happen from any thread or CPU core.
407- unsafe impl Send for MmioCam { }
408-
409407// SAFETY: `&MmioCam` only allows MMIO reads, which are fine to happen concurrently on different CPU
410408// cores.
411- unsafe impl Sync for MmioCam { }
409+ unsafe impl Sync for MmioCam < ' _ > { }
412410
413411/// Information about a PCI Base Address Register.
414412#[ derive( Clone , Debug , Eq , PartialEq ) ]
0 commit comments