@@ -26,8 +26,8 @@ unsafe {
2626}
2727```
2828
29- Depending on your platform this will either use ` write_volatile ` or some platform-dependent inline
30- assembly to perform the MMIO write.
29+ Depending on your platform this will either use ` write_volatile ` , some platform-dependent inline
30+ assembly, or a [ custom backend ] ( #custom-mmio-backend ) to perform the MMIO write.
3131
3232### Safe MMIO methods
3333
@@ -92,6 +92,53 @@ should never be more than one `PhysicalInstance` pointer to the same device. Thi
9292table management code can take a ` PhysicalInstance<T> ` and return a ` UniqueMmioPointer<T> ` when a
9393device is mapped into the page table.
9494
95+ ### Custom MMIO backend
96+
97+ Some environments need to intercept MMIO accesses instead of letting them hit
98+ hardware directly. The ` custom-mmio ` feature lets the consuming project inject
99+ its own read/write implementations, even across the dependency chain, while
100+ keeping the rest of the safe-mmio API unchanged.
101+
102+ Enable the feature in your ` Cargo.toml ` :
103+
104+ ``` toml
105+ [dependencies ]
106+ safe-mmio = { version = " 0.3.0" , features = [" custom-mmio" ] }
107+ ```
108+
109+ Then implement the ` MmioOps ` trait and register it with ` set_mmio_ops! ` :
110+
111+ ``` rust
112+ use safe_mmio :: custom_mmio :: MmioOps ;
113+
114+ struct MyBackend ;
115+
116+ // SAFETY: Each method performs a single MMIO access of the indicated width.
117+ unsafe impl MmioOps for MyBackend {
118+ unsafe fn read_u8 (src : * const u8 ) -> u8 { /* ... */ }
119+ unsafe fn read_u16 (src : * const u16 ) -> u16 { /* ... */ }
120+ unsafe fn read_u32 (src : * const u32 ) -> u32 { /* ... */ }
121+ unsafe fn read_u64 (src : * const u64 ) -> u64 { /* ... */ }
122+ unsafe fn write_u8 (dst : * mut u8 , value : u8 ) { /* ... */ }
123+ unsafe fn write_u16 (dst : * mut u16 , value : u16 ) { /* ... */ }
124+ unsafe fn write_u32 (dst : * mut u32 , value : u32 ) { /* ... */ }
125+ unsafe fn write_u64 (dst : * mut u64 , value : u64 ) { /* ... */ }
126+ }
127+
128+ safe_mmio :: set_mmio_ops! (MyBackend );
129+ ```
130+
131+ The ` set_mmio_ops! ` macro generates ` #[no_mangle] ` functions that the library resolves via
132+ ` extern "Rust" ` declarations. Exactly one call must exist in the final binary; linking fails
133+ otherwise.
134+
135+ When ` custom-mmio ` is enabled it replaces both the default ` volatile ` backend and the ` aarch64 `
136+ inline-assembly backend.
137+
138+ ** Testing note:** Unit tests (` cargo test --lib --features custom-mmio ` ) work because the library
139+ includes a volatile-based ` MmioOps ` implementation gated on ` #[cfg(test)] ` . Doc tests build as
140+ separate binaries and cannot see ` #[cfg(test)] ` items, so use ` --lib ` to skip them.
141+
95142## Comparison with other MMIO crates
96143
97144There are a number of things that distinguish this crate from other crates providing abstractions
0 commit comments