@@ -187,6 +187,45 @@ impl<const SIZE: usize> IoMem<SIZE> {
187
187
crate :: build_assert!( Self :: offset_ok:: <T >( offset) , "IoMem offset overflow" ) ;
188
188
}
189
189
190
+ /// Copy memory block from an i/o memory by filling the specified buffer with it.
191
+ ///
192
+ /// # Examples
193
+ /// ```
194
+ /// # use kernel::prelude::*;
195
+ /// use kernel::io_mem::{self, IoMem, Resource};
196
+ ///
197
+ /// fn test(res: Resource) -> Result {
198
+ /// // Create an i/o memory block of at least 100 bytes.
199
+ /// let mem = unsafe { IoMem::<100>::try_new(res) }?;
200
+ ///
201
+ /// let mut buffer: [u8; 32] = [0; 32];
202
+ ///
203
+ /// // Memcpy 16 bytes from an offset 10 of i/o memory block into the buffer.
204
+ /// mem.try_memcpy_fromio(&mut buffer[..16], 10)?;
205
+ ///
206
+ /// Ok(())
207
+ /// }
208
+ /// ```
209
+ pub fn try_memcpy_fromio ( & self , buffer : & mut [ u8 ] , offset : usize ) -> Result {
210
+ if !Self :: offset_ok_of_val ( offset, buffer) {
211
+ return Err ( EINVAL ) ;
212
+ }
213
+
214
+ let ptr = self . ptr . wrapping_add ( offset) ;
215
+
216
+ // SAFETY:
217
+ // - The type invariants guarantee that `ptr` is a valid pointer.
218
+ // - The bounds of `buffer` are checked with a call to `offset_ok_of_val()`.
219
+ unsafe {
220
+ bindings:: memcpy_fromio (
221
+ buffer. as_mut_ptr ( ) as * mut _ ,
222
+ ptr as * const _ ,
223
+ buffer. len ( ) as _ ,
224
+ )
225
+ } ;
226
+ Ok ( ( ) )
227
+ }
228
+
190
229
define_read ! ( readb, try_readb, u8 ) ;
191
230
define_read ! ( readw, try_readw, u16 ) ;
192
231
define_read ! ( readl, try_readl, u32 ) ;
0 commit comments