@@ -441,7 +441,7 @@ fn create_psci_node(fdt: &mut Vec<u8>) -> Result<()> {
441441
442442fn create_virtio_node < T : DeviceInfoForFDT + Clone + Debug > (
443443 fdt : & mut Vec < u8 > ,
444- dev_info : T ,
444+ dev_info : & T ,
445445) -> Result < ( ) > {
446446 let device_reg_prop = generate_prop64 ( & [ dev_info. addr ( ) , dev_info. length ( ) ] ) ;
447447 let irq = generate_prop32 ( & [ GIC_FDT_IRQ_TYPE_SPI , dev_info. irq ( ) , IRQ_TYPE_EDGE_RISING ] ) ;
@@ -458,7 +458,7 @@ fn create_virtio_node<T: DeviceInfoForFDT + Clone + Debug>(
458458
459459fn create_serial_node < T : DeviceInfoForFDT + Clone + Debug > (
460460 fdt : & mut Vec < u8 > ,
461- dev_info : T ,
461+ dev_info : & T ,
462462) -> Result < ( ) > {
463463 let serial_reg_prop = generate_prop64 ( & [ dev_info. addr ( ) , dev_info. length ( ) ] ) ;
464464 let irq = generate_prop32 ( & [ GIC_FDT_IRQ_TYPE_SPI , dev_info. irq ( ) , IRQ_TYPE_EDGE_RISING ] ) ;
@@ -476,7 +476,7 @@ fn create_serial_node<T: DeviceInfoForFDT + Clone + Debug>(
476476
477477fn create_rtc_node < T : DeviceInfoForFDT + Clone + Debug > (
478478 fdt : & mut Vec < u8 > ,
479- dev_info : T ,
479+ dev_info : & T ,
480480) -> Result < ( ) > {
481481 let compatible = b"arm,pl031\0 arm,primecell\0 " ;
482482 let rtc_reg_prop = generate_prop64 ( & [ dev_info. addr ( ) , dev_info. length ( ) ] ) ;
@@ -496,35 +496,23 @@ fn create_devices_node<T: DeviceInfoForFDT + Clone + Debug>(
496496 fdt : & mut Vec < u8 > ,
497497 dev_info : & HashMap < ( DeviceType , String ) , T > ,
498498) -> Result < ( ) > {
499- // We are trying to detect the root block device. We know
500- // that if a root block device is attached, it will be the one with the lowest bus address.
501-
502- // As per doc, `None` will be returned only if the iterator
503- // is empty. That cannot happen, since on aarch64 the RTC device is
504- // always appended to the hashmap of devices.
505- let ( ( first_device_type, first_device_id) , first_device_info) = dev_info
506- . iter ( )
507- . min_by ( |& ( _, ref a) , & ( _, ref b) | a. addr ( ) . cmp ( & b. addr ( ) ) )
508- . expect ( "Device Information cannot be empty" ) ;
509-
510- // We check that the device with the lowest bus address is indeed a virtio device.
511- // At this point, it does not matter whether we are dealing with network or block since
512- // the create_virtio_node function is agnostic of that.
513- if let DeviceType :: Virtio ( _) = first_device_type {
514- create_virtio_node ( fdt, first_device_info. clone ( ) ) ?;
515- }
499+ // Create one temp Vec to store all virtio devices
500+ let mut ordered_virtio_device: Vec < & T > = Vec :: new ( ) ;
516501
517502 for ( ( device_type, device_id) , info) in dev_info {
518503 match device_type {
519- DeviceType :: RTC => create_rtc_node ( fdt, info. clone ( ) ) ?,
520- DeviceType :: Serial => create_serial_node ( fdt, info. clone ( ) ) ?,
504+ DeviceType :: RTC => create_rtc_node ( fdt, info) ?,
505+ DeviceType :: Serial => create_serial_node ( fdt, info) ?,
521506 DeviceType :: Virtio ( _) => {
522- // We already appended the first virtio device.
523- if ( device_type, device_id) != ( & first_device_type, & first_device_id) {
524- create_virtio_node ( fdt, info. clone ( ) ) ?;
525- }
507+ ordered_virtio_device. push ( info) ;
526508 }
527- } ;
509+ }
510+ }
511+
512+ // Sort out virtio devices by address from low to high and insert them into fdt table.
513+ ordered_virtio_device. sort_by ( |a, b| a. addr ( ) . cmp ( & b. addr ( ) ) ) ;
514+ for ordered_device_info in ordered_virtio_device. drain ( ..) {
515+ create_virtio_node ( fdt, ordered_device_info) ?;
528516 }
529517
530518 Ok ( ( ) )
0 commit comments