@@ -234,3 +234,125 @@ impl IoManager {
234
234
}
235
235
}
236
236
}
237
+
238
+ #[ cfg( test) ]
239
+ mod tests {
240
+ use super :: * ;
241
+ use std:: sync:: Mutex ;
242
+
243
+ const PIO_ADDRESS_SIZE : u16 = 4 ;
244
+ const PIO_ADDRESS_BASE : u16 = 0x40 ;
245
+ const MMIO_ADDRESS_SIZE : u64 = 0x8765_4321 ;
246
+ const MMIO_ADDRESS_BASE : u64 = 0x1234_5678 ;
247
+ const LEGACY_IRQ : u32 = 4 ;
248
+ const CONFIG_DATA : u32 = 0x1234 ;
249
+
250
+ struct DummyDevice {
251
+ config : Mutex < u32 > ,
252
+ }
253
+
254
+ impl DummyDevice {
255
+ fn new ( config : u32 ) -> Self {
256
+ DummyDevice {
257
+ config : Mutex :: new ( config) ,
258
+ }
259
+ }
260
+ }
261
+
262
+ impl DeviceIo for DummyDevice {
263
+ fn read ( & self , _base : IoAddress , _offset : IoAddress , data : & mut [ u8 ] ) {
264
+ if data. len ( ) > 4 {
265
+ return ;
266
+ }
267
+ for ( idx, iter) in data. iter_mut ( ) . enumerate ( ) {
268
+ let config = self . config . lock ( ) . expect ( "failed to acquire lock" ) ;
269
+ * iter = ( * config >> ( idx * 8 ) & 0xff ) as u8 ;
270
+ }
271
+ }
272
+
273
+ fn write ( & self , _base : IoAddress , _offset : IoAddress , data : & [ u8 ] ) {
274
+ let mut config = self . config . lock ( ) . expect ( "failed to acquire lock" ) ;
275
+ * config = u32:: from ( data[ 0 ] ) & 0xff ;
276
+ }
277
+ }
278
+
279
+ #[ test]
280
+ fn test_register_unregister_device_io ( ) {
281
+ let mut io_mgr = IoManager :: new ( ) ;
282
+ let dummy = DummyDevice :: new ( 0 ) ;
283
+ let dum = Arc :: new ( dummy) ;
284
+
285
+ let mut resource: Vec < Resource > = Vec :: new ( ) ;
286
+ let mmio = Resource :: MmioAddressRange {
287
+ base : MMIO_ADDRESS_BASE ,
288
+ size : MMIO_ADDRESS_SIZE ,
289
+ } ;
290
+ let irq = Resource :: LegacyIrq ( LEGACY_IRQ ) ;
291
+
292
+ resource. push ( mmio) ;
293
+ resource. push ( irq) ;
294
+
295
+ assert ! ( io_mgr. register_device_io( dum. clone( ) , & resource) . is_ok( ) ) ;
296
+ assert ! ( io_mgr. unregister_device_io( & resource) . is_ok( ) )
297
+ }
298
+
299
+ #[ test]
300
+ fn test_mmio_read_write ( ) {
301
+ let mut io_mgr: IoManager = Default :: default ( ) ;
302
+ let dum = Arc :: new ( DummyDevice :: new ( CONFIG_DATA ) ) ;
303
+ let mut resource: Vec < Resource > = Vec :: new ( ) ;
304
+
305
+ let mmio = Resource :: MmioAddressRange {
306
+ base : MMIO_ADDRESS_BASE ,
307
+ size : MMIO_ADDRESS_SIZE ,
308
+ } ;
309
+ resource. push ( mmio) ;
310
+ assert ! ( io_mgr. register_device_io( dum. clone( ) , & resource) . is_ok( ) ) ;
311
+
312
+ let mut data = [ 0 ; 4 ] ;
313
+ assert ! ( io_mgr. mmio_read( MMIO_ADDRESS_BASE , & mut data) . is_ok( ) ) ;
314
+ assert_eq ! ( data, [ 0x34 , 0x12 , 0 , 0 ] ) ;
315
+
316
+ assert ! ( io_mgr
317
+ . mmio_read( MMIO_ADDRESS_BASE + MMIO_ADDRESS_SIZE , & mut data)
318
+ . is_err( ) ) ;
319
+
320
+ data = [ 0 ; 4 ] ;
321
+ assert ! ( io_mgr. mmio_write( MMIO_ADDRESS_BASE , & data) . is_ok( ) ) ;
322
+ assert_eq ! ( * dum. config. lock( ) . unwrap( ) , 0 ) ;
323
+
324
+ assert ! ( io_mgr
325
+ . mmio_write( MMIO_ADDRESS_BASE + MMIO_ADDRESS_SIZE , & data)
326
+ . is_err( ) ) ;
327
+ }
328
+
329
+ #[ test]
330
+ fn test_pio_read_write ( ) {
331
+ let mut io_mgr: IoManager = Default :: default ( ) ;
332
+ let dum = Arc :: new ( DummyDevice :: new ( CONFIG_DATA ) ) ;
333
+ let mut resource: Vec < Resource > = Vec :: new ( ) ;
334
+
335
+ let pio = Resource :: PioAddressRange {
336
+ base : PIO_ADDRESS_BASE ,
337
+ size : PIO_ADDRESS_SIZE ,
338
+ } ;
339
+ resource. push ( pio) ;
340
+ assert ! ( io_mgr. register_device_io( dum. clone( ) , & resource) . is_ok( ) ) ;
341
+
342
+ let mut data = [ 0 ; 4 ] ;
343
+ assert ! ( io_mgr. pio_read( PIO_ADDRESS_BASE , & mut data) . is_ok( ) ) ;
344
+ assert_eq ! ( data, [ 0x34 , 0x12 , 0 , 0 ] ) ;
345
+
346
+ assert ! ( io_mgr
347
+ . pio_read( PIO_ADDRESS_BASE + PIO_ADDRESS_SIZE , & mut data)
348
+ . is_err( ) ) ;
349
+
350
+ data = [ 0 ; 4 ] ;
351
+ assert ! ( io_mgr. pio_write( PIO_ADDRESS_BASE , & data) . is_ok( ) ) ;
352
+ assert_eq ! ( * dum. config. lock( ) . unwrap( ) , 0 ) ;
353
+
354
+ assert ! ( io_mgr
355
+ . pio_write( PIO_ADDRESS_BASE + PIO_ADDRESS_SIZE , & data)
356
+ . is_err( ) ) ;
357
+ }
358
+ }
0 commit comments