pvmfw: Use feasible iommus for device assignment test

This CL includes following fixes for preparing iommu validation with
token from hypervisor.
  - Provide <android,pvmfw,phy-iommus> for device with iommus.
  - Ensure #iommu-cells = <1>
  - Ensure that (pvIOMMU, vSID) and (phys IOMMU ID, phys SID) have 1:1
    mapping.
  - Match number of pvIOMMU/vSID in FDT with VM DTBO's.

This CL doesn't fix <reg> to minimize change.

Bug: 277993056
Test: atest libpvmfw.device_assignment.test, launch protected VM
Change-Id: I3a6f600f0468bc24e818c1772bf8048ee4b41b11
diff --git a/pvmfw/src/device_assignment.rs b/pvmfw/src/device_assignment.rs
index 60bf21c..14f1fe5 100644
--- a/pvmfw/src/device_assignment.rs
+++ b/pvmfw/src/device_assignment.rs
@@ -452,8 +452,8 @@
     const VM_DTBO_FILE_PATH: &str = "test_pvmfw_devices_vm_dtbo.dtbo";
     const VM_DTBO_WITHOUT_SYMBOLS_FILE_PATH: &str =
         "test_pvmfw_devices_vm_dtbo_without_symbols.dtbo";
+    const FDT_WITHOUT_IOMMUS_FILE_PATH: &str = "test_pvmfw_devices_without_iommus.dtb";
     const FDT_FILE_PATH: &str = "test_pvmfw_devices_with_rng.dtb";
-    const FDT_WITH_IOMMU_FILE_PATH: &str = "test_pvmfw_devices_with_rng_iommu.dtb";
     const FDT_WITH_MULTIPLE_DEVICES_IOMMUS_FILE_PATH: &str =
         "test_pvmfw_devices_with_multiple_devices_iommus.dtb";
     const FDT_WITH_IOMMU_SHARING: &str = "test_pvmfw_devices_with_iommu_sharing.dtb";
@@ -464,7 +464,7 @@
         path: CString,
         reg: Vec<u8>,
         interrupts: Vec<u8>,
-        iommus: Vec<u32>, // pvIOMMU ids
+        iommus: Vec<u32>, // pvIOMMU id and vSID
     }
 
     impl AssignedDeviceNode {
@@ -536,6 +536,26 @@
     }
 
     #[test]
+    fn device_info_assigned_info_without_iommus() {
+        let mut fdt_data = fs::read(FDT_WITHOUT_IOMMUS_FILE_PATH).unwrap();
+        let mut vm_dtbo_data = fs::read(VM_DTBO_FILE_PATH).unwrap();
+        let fdt = Fdt::from_mut_slice(&mut fdt_data).unwrap();
+        let vm_dtbo = VmDtbo::from_mut_slice(&mut vm_dtbo_data).unwrap();
+
+        let device_info = DeviceAssignmentInfo::parse(fdt, vm_dtbo).unwrap().unwrap();
+
+        let expected = [AssignedDeviceInfo {
+            node_path: CString::new("/backlight").unwrap(),
+            dtbo_node_path: cstr!("/fragment@backlight/__overlay__/backlight").into(),
+            reg: into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]),
+            interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
+            iommus: vec![],
+        }];
+
+        assert_eq!(device_info.assigned_devices, expected);
+    }
+
+    #[test]
     fn device_info_assigned_info() {
         let mut fdt_data = fs::read(FDT_FILE_PATH).unwrap();
         let mut vm_dtbo_data = fs::read(VM_DTBO_FILE_PATH).unwrap();
@@ -549,7 +569,7 @@
             dtbo_node_path: cstr!("/fragment@rng/__overlay__/rng").into(),
             reg: into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]),
             interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
-            iommus: vec![],
+            iommus: vec![(PvIommu { id: 0x4 }, Vsid(0xFF0))],
         }];
 
         assert_eq!(device_info.assigned_devices, expected);
@@ -585,13 +605,19 @@
         let light = vm_dtbo.node(cstr!("/fragment@rng/__overlay__/light")).unwrap();
         assert_eq!(light, None);
 
+        let led = vm_dtbo.node(cstr!("/fragment@led/__overlay__/led")).unwrap();
+        assert_eq!(led, None);
+
+        let backlight = vm_dtbo.node(cstr!("/fragment@backlight/__overlay__/backlight")).unwrap();
+        assert_eq!(backlight, None);
+
         let symbols_node = vm_dtbo.symbols().unwrap();
         assert_eq!(symbols_node, None);
     }
 
     #[test]
     fn device_info_patch() {
-        let mut fdt_data = fs::read(FDT_FILE_PATH).unwrap();
+        let mut fdt_data = fs::read(FDT_WITHOUT_IOMMUS_FILE_PATH).unwrap();
         let mut vm_dtbo_data = fs::read(VM_DTBO_FILE_PATH).unwrap();
         let mut data = vec![0_u8; fdt_data.len() + vm_dtbo_data.len()];
         let fdt = Fdt::from_mut_slice(&mut fdt_data).unwrap();
@@ -610,14 +636,14 @@
         // Note: Intentionally not using AssignedDeviceNode for matching all props.
         type FdtResult<T> = libfdt::Result<T>;
         let expected: Vec<(FdtResult<&CStr>, FdtResult<Vec<u8>>)> = vec![
-            (Ok(cstr!("android,rng,ignore-gctrl-reset")), Ok(Vec::new())),
-            (Ok(cstr!("compatible")), Ok(Vec::from(*b"android,rng\0"))),
+            (Ok(cstr!("android,backlight,ignore-gctrl-reset")), Ok(Vec::new())),
+            (Ok(cstr!("compatible")), Ok(Vec::from(*b"android,backlight\0"))),
             (Ok(cstr!("interrupts")), Ok(into_fdt_prop(vec![0x0, 0xF, 0x4]))),
             (Ok(cstr!("iommus")), Ok(Vec::new())),
             (Ok(cstr!("reg")), Ok(into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]))),
         ];
 
-        let rng_node = platform_dt.node(cstr!("/rng")).unwrap().unwrap();
+        let rng_node = platform_dt.node(cstr!("/backlight")).unwrap().unwrap();
         let mut properties: Vec<_> = rng_node
             .properties()
             .unwrap()
@@ -634,7 +660,7 @@
 
     #[test]
     fn device_info_overlay_iommu() {
-        let mut fdt_data = fs::read(FDT_WITH_IOMMU_FILE_PATH).unwrap();
+        let mut fdt_data = fs::read(FDT_FILE_PATH).unwrap();
         let mut vm_dtbo_data = fs::read(VM_DTBO_FILE_PATH).unwrap();
         let fdt = Fdt::from_mut_slice(&mut fdt_data).unwrap();
         let vm_dtbo = VmDtbo::from_mut_slice(&mut vm_dtbo_data).unwrap();
@@ -691,13 +717,13 @@
                 path: CString::new("/rng").unwrap(),
                 reg: into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]),
                 interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
-                iommus: vec![0x4, 0xFF0, 0x9, 0xFF1],
+                iommus: vec![0x4, 0xFF0],
             },
             AssignedDeviceNode {
                 path: CString::new("/light").unwrap(),
                 reg: into_fdt_prop(vec![0x100, 0x9]),
                 interrupts: into_fdt_prop(vec![0x0, 0xF, 0x5]),
-                iommus: vec![0x40, 0xFFA, 0x50, 0xFFB, 0x60, 0xFFC],
+                iommus: vec![0x40, 0xFFA, 0x50, 0xFFB],
             },
         ];
 
@@ -706,7 +732,7 @@
             assert_eq!(node, Ok(expected));
         }
         let pviommus = collect_pviommus(platform_dt);
-        assert_eq!(pviommus, Ok(vec![0x4, 0x9, 0x40, 0x50, 0x60]));
+        assert_eq!(pviommus, Ok(vec![0x4, 0x40, 0x50]));
     }
 
     #[test]
@@ -734,13 +760,13 @@
                 path: CString::new("/rng").unwrap(),
                 reg: into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]),
                 interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
-                iommus: vec![0x4, 0xFF0, 0x9, 0xFF1],
+                iommus: vec![0x4, 0xFF0],
             },
             AssignedDeviceNode {
-                path: CString::new("/light").unwrap(),
+                path: CString::new("/led").unwrap(),
                 reg: into_fdt_prop(vec![0x100, 0x9]),
                 interrupts: into_fdt_prop(vec![0x0, 0xF, 0x5]),
-                iommus: vec![0x9, 0xFF1, 0x40, 0xFFA],
+                iommus: vec![0x4, 0xFF0],
             },
         ];
 
@@ -750,7 +776,7 @@
         }
 
         let pviommus = collect_pviommus(platform_dt);
-        assert_eq!(pviommus, Ok(vec![0x4, 0x9, 0x40]));
+        assert_eq!(pviommus, Ok(vec![0x4]));
     }
 
     #[test]